psycopg2映射的Python:到Postgres的“类型的字典的列表”:“复合类型的数组” I

2019-06-27 00:59发布

Postgres的版本:9.1.x.

说我有以下模式:

DROP TABLE IF EXISTS posts CASCADE;
DROP TYPE IF EXISTS quotes CASCADE;

CREATE TYPE quotes AS
(
  text  CHARACTER VARYING,
  is_direct CHARACTER VARYING
);

CREATE TABLE posts
(
    body  CHARACTER VARYING,
    q     quotes[]
);

我希望执行下列插入,在SQL显示,但在Python Psycopg2。

insert into posts(body,q) VALUES('ninjas rock',ARRAY[ ROW('I AGREE',True)::quotes, ROW('I DISAGREE',FALSE)::quotes ]);

什么是语法来实现这一目标(不循环和这样)。 我相信这是可能的,因为文件说, “在2.4.3版本中更改:添加了复合类型的阵列支持”。 该文件只显示的示例SELECT语句。

注:我在我的客户端代码类型的字典,在概念映射到伪模式上面的列表。

编辑:

嗯,我必须错过了这个从文档:“适应从Python的元组复合类型是自动的,而不是,不需要适配器注册。” 。 现在要弄清楚的阵列部分。

编辑2:

psycopg2的%s时传递的数据类型是占位符应工作list(tuple)list(dict) 。 总得测试一下:d

EDIT3:好的差不多了,http://stardict.sourceforge.net/Dictionaries.php下载不工作在这种情况下,列表做的,元组做。 不过,我需要的元组字符串表示抛入复合记录类型。

这个 :

quote_1 = ("monkeys rock", "False")
quote_2 = ("donkeys rock",  "True")
q_list = [ quote_1, quote_2]
print cur.mogrify("insert into posts VALUES(%s,%s)", ("animals are good", q_list))

创建以下字符串:

insert into posts VALUES('animals are good',ARRAY[('monkeys rock', 'false'), ('donkeys rock', 'true')])

这产生以下错误:

psycopg2.ProgrammingError: column "q" is of type quotes[] but expression is of type record[]

Answer 1:

扩展你的努力只是一点点,怎么样:

quote_1 = ("monkeys rock", "False")
quote_2 = ("donkeys rock",  "True")
q_list = [ quote_1, quote_2]
print cur.mogrify("insert into posts VALUES(%s,%s::quotes[])", 
                  ("animals are good", q_list))
#
#                 added explicit cast to quotes[]->^^^^^^^^

说明

如果你运行:

insert into posts 
VALUES('animals are good', ARRAY[
    ('monkeys rock', 'false'),
    ('donkeys rock', 'true')
]);

直接在psql ,你会得到:

regress=# insert into posts 
regress-# VALUES('animals are good',ARRAY[
regress-#             ('monkeys rock', 'false'),
regress-#             ('donkeys rock', 'true')
regress-#  ]);
ERROR:  column "q" is of type quotes[] but expression is of type record[]
LINE 1: insert into posts VALUES('animals are good',ARRAY[('monkeys ...
                                                    ^
HINT:  You will need to rewrite or cast the expression.

果然,告诉PG你匿名数组类型的quotes[]的伎俩:

regress=# insert into posts 
regress-# VALUES('animals are good',ARRAY[
regress-#           ('monkeys rock', 'false'),
regress-#           ('donkeys rock', 'true')
regress-# ]::quotes[]);
INSERT 0 1

regress=# select * from posts;
       body       |                           q                            
------------------+--------------------------------------------------------
 animals are good | {"(\"monkeys rock\",false)","(\"donkeys rock\",true)"}
(1 row)


文章来源: psycopg2 mapping Python : “list of dicts” to Postgres : “array of composite type” for an INSERT statement