要快速从Python数组转换为PostgreSQL吗?

这是一个后续问题:
How to cast to int array in PostgreSQL?

我正在考虑如何快速将Python的有符号整数数组的数据类型转换为PostgreSQL的int:

import numpy as np; # use any data format of Python here
event = np.array([[1,2],[3,4]]);

其中[]应替换为{}并用’if手动包围.
在PostgreSQL中,以下内容被接受为数据类型的语法

...
FOR EACH ROW EXECUTE PROCEDURE insaft_function('{{1,2},{3,4}}'); 

@ JohnMee的建议

str(event).replace('[','{').replace(']','}').replace('\n ',',')

@ ErwinBrandstetter的建议

坚持使用有符号整数,因为SQL标准支持它.
映射到int,所以只是在PostgreSQL方面:

TG_ARGV::int[]

我想坚持这个欧文的建议.

测试更简单版本的@ ErwinBrandstetter的答案

我必须通过从函数中删除表名来简化他的答案以保持足够的重点,这样只需保留一个初始表测量的触发器:

CREATE OR REPLACE FUNCTION f_create_my_trigger(_arg0 text)
  RETURNS void AS
$func$
BEGIN
EXECUTE format($$
    DROP TRIGGER IF EXISTS insaft_ids ON measurements;
    CREATE TRIGGER insaft_ids
    AFTER INSERT ON measurements
    FOR EACH ROW EXECUTE PROCEDURE insaft_function(%1$L)$$
    , _arg0
);

END
$func$LANGUAGE plpgsql;

我跑:

sudo -u postgres psql detector -c "SELECT f_create_my_trigger('[[1,2],[3,4]]');"

但得到空输出:

 f_create_my_trigger 
---------------------

(1 row)

如何在Python中映射到PostgreSQL 9.4的int?

最佳答案 总结情况

您想使用与my previous answer on dba.SE中概述的相同的触发函数来创建触发器(重复?).您需要将值传递给触发器函数以创建具有多个列值的多行,因此创建二维数组. (但我们可以使用任何明确定义的字符串!)

将值传递给PL / pgSQL触发器函数的唯一方法是文本参数,可以在函数内部访问0-based array of text TG_ARGV[].您可以传递可变数量的参数,但我们之前讨论过表示2维数组的单个字符串文字.

您想要传递的值来自具有有符号整数的2维Python数组,因此它们将适合Postgres整数类型.你必须使用Postgres类型bigint来确定无符号整数,like I commented.

Python中的文本表示如下所示:

[[1,2],[3,4]]

Postgres数组文字的语法如下所示:

{{1,2},{3,4}}

似乎你想要自动化这个过程.

完全自动化

您可以在客户端中连接CREATE TRIGGER语句的字符串,也可以在服务器端函数中保留逻辑并只传递参数.

演示一个示例函数,我们将表名和用作参数的字符串传递给触发器函数.触发功能insaft_function() is defined in your previous question on dba.SE.

CREATE OR REPLACE FUNCTION f_create_my_trigger(_tbl regclass, _arg0 text)
  RETURNS void AS
$func$
BEGIN

EXECUTE format($$
   DROP TRIGGER IF EXISTS insaft_%1$s_ids ON %1$s;
   CREATE TRIGGER insaft_%1$s_ids
   AFTER INSERT ON %1$s
   FOR EACH ROW EXECUTE PROCEDURE insaft_function(%2$L)$$
   , _tbl, translate(_arg0, '[]', '{}')
   );

END 
$func$LANGUAGE plpgsql;

呼叫:

SELECT f_create_my_trigger('measurements', '[[1,2],[3,4]]');

要么:

SELECT f_create_my_trigger('some_other_table', '{{5,6},{7,8}}');

SQL Fiddle演示.

现在你可以传递[[1,2],[3,4]](带方括号)或{{1,2},{3,4}}(带花括号).两者都是一样的. translate(_arg0,'[]’,'{}’将第一个转换为第二个形式.

在创建新触发器之前,此函数会自动删除相同名称的触发器(如果存在).您可能想要删除或保留此行:

DROP TRIGGER IF EXISTS insaft_%1$s_ids ON %1$s;

它以调用DB角色的权限运行.如果需要,你可以把它变成run with superuser (or any other) privileges.

还有很多其他方法可以实现这一目标.这完全取决于具体要求.

解释format()

format()和数据类型regclass有助于安全地连接DDL命令,同时使SQL注入无法进行.细节:

> Table name as a PostgreSQL function parameter

第一个参数是“格式字符串”,后面跟着要嵌入字符串的参数.我使用的是dollar-quoting,这对于示例来说并不是绝对必要的,但通常是连接可能包含文字引号的长字符串的好主意:$$DROP TRIGGER … $$

format()是沿着C函数sprintf建模的. %1 $s是format()函数的格式说明符.这意味着格式字符串之后的第一个(1 $)参数作为不带引号的字符串(%s)插入,因此:%1 $s.格式的第一个参数是示例中的_tbl – regclass参数自动呈现为合法标识符,必要时双引号,因此format()不必执行更多操作.因此只是%s,而不是%I(标识符).阅读上面的链接答案了解详情.
使用的另一个格式说明符是%2 $L:第二个参数作为带引号的字符串文字.

如果您不熟悉format(),请使用这些简单的示例来理解:

SELECT format('input -->|%s|<-- here', '[1,2]')
     , format('input -->|%s|<-- here', translate('[1,2]', '[]', '{}'))
     , format('input -->|%L|<-- here', translate('[1,2]', '[]', '{}'))
     , format('input -->|%I|<-- here', translate('[1,2]', '[]', '{}'));

read the manual.

点赞