簡體   English   中英

psycopg2將Python:“字典列表”映射到Postgres:“ INSERT語句的復合類型數組”

[英]psycopg2 mapping Python : “list of dicts” to Postgres : “array of composite type” for an INSERT statement

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語句的示例。

注意:我的客戶端代碼中有一系列字典,這些字典在概念上映射到上面的psuedo模式。

編輯:

嗯,我一定從文檔中錯過了這一點: “相反,從Python元組到復合類型的自適應是自動的,不需要適配器注冊。” 現在找出陣列部分。

編輯2:

當傳遞的數據類型為list(tuple)list(dict)時,psycopg2的%s占位符應該起作用。 要測試一下:D

edit3:好的,在這種情況下,字典不起作用,列表起作用,而元組起作用。 但是,我需要將元組字符串表示形式轉換為復合記錄類型。

這個 :

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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM