問題
我正在努力將資料插入到帶有 Python 中自定義資料型別陣列列的表中。
該方案如下所示:
CREATE TYPE data_source AS ENUM ('smtp', 'ftp', 'http');
CREATE TABLE IF NOT EXISTS data(
id BIGSERIAL PRIMARY KEY,
foo TEXT NOT NULL,
sources data_source[]
);
然后,我想使用 psycopg2 從 Python 將一些資料插入到這樣的表中:
foo = "my_text"
sources = ["ftp", "http"]
cursor.execute(
"""
INSERT INTO data(foo, sources)
VALUES (%s, %s)
""",
(foo, sources),
)
此代碼以運行時例外結束:
LINE 3: ...('my text', ARRAY['ftp...
^
HINT: You will need to rewrite or cast the expression.
我明白,我需要呼叫::data_source型別轉換到每個元素ARRAY。我怎樣才能做到這一點?
帶有 class 和 adapt() 的變體
我試圖利用包中的adapt功能psycopg2.extensions
class Source:
def __init__(self, source):
self.string = source
def adapt_source(source):
quoted = psycopg2.extensions.adapt(source.string).getquoted()
return psycopg2.extensions.AsIs(f"{quoted}::data_source'")
psycopg2.extensions.register_adapter(Source, adapt_source)
foo = "my_text"
sources = [Source("ftp"), Source("http")]
cursor.execute(
"""
INSERT INTO data(foo, sources)
VALUES (%s, %s)
""",
(foo, sources),
)
但這段代碼最終是:
psycopg2.errors.SyntaxError: syntax error at or near ""'ftp'""
LINE 3: ...my text', (b"'ftp'"::...
^
我猜問題出在AsIs函式中,它結合了函式和格式化字串中的位元組。getquoted
任何人都可以幫助我或向我指出任何解決方案嗎?
謝謝
uj5u.com熱心網友回復:
我在評論中提出的完整示例:
CREATE TYPE data_source AS ENUM ('smtp', 'ftp', 'http');
CREATE TABLE IF NOT EXISTS data(
id BIGSERIAL PRIMARY KEY,
foo TEXT NOT NULL,
sources data_source[]
);
import psycopg2
con = psycopg2.connect(database="test", host='localhost', user='postgres')
cur = con.cursor
foo = "my_text"
source_list = ["ftp", "http"]
sources = '{' ','.join(source_list) '}'
sources
'{ftp,http}'
cur.execute(
"""
INSERT INTO data(foo, sources)
VALUES (%s, %s)
""",
(foo, sources),
)
con.commit()
select * from data;
id | foo | sources
---- --------- ------------
1 | my_text | {ftp,http}
將源串列轉換為陣列的字串表示形式,并將其用作sources值。
uj5u.com熱心網友回復:
擴展阿德里安Klaver的答案,你還需要投的資料庫型別data_source,你在架構中定義。
cur.execute(
"""
INSERT INTO data(foo, sources)
VALUES (%s, %s::data_source[])
""",
(foo, sources),
)
con.commit()
這對我有用。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/324281.html
