ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2019-11-01 01:06:10  阅读:321  来源: 互联网

标签:postgresql orm relational-database psycopg2 python


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 ]);

实现此目的的语法是什么(没有循环等).我确信自documentation says“在2.4.3版中已更改:添加了对复合类型数组的支持”以来,这是可能的.该文档仅显示SELECT语句的示例.

注意:我的客户端代码中有一系列字典,这些字典在概念上映射到上面的psuedo模式.

编辑:

嗯,我一定从文档中错过了这一点:“相反,从Python元组到复合类型的自适应是自动的,不需要适配器注册.”现在找出阵列部分.

编辑2:

当传递的数据类型为list(tuple)或list(dict)时,psycopg2的%s占位符应该起作用.要测试一下:D

编辑3:
好的,到此为止,字典在这种情况下不起作用,列表可以,而元组可以.但是,我需要将元组字符串表示形式转换为复合记录类型.

这个 :

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[]

解决方法:

稍加努力,如何:

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)

标签:postgresql,orm,relational-database,psycopg2,python
来源: https://codeday.me/bug/20191101/1980075.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有