我在 postgres 中有一个表,我想使用 duckdb 插入其中。我对表有一个唯一约束,它使用多个列来确定唯一行。发生冲突时,应忽略重复的行。
这是我用来设置它的代码(在课堂上,但没有什么区别)
self.conn = duckdb.connect()
self.conn.install_extension('postgres')
self.conn.load_extension('postgres')
self.conn.sql("ATTACH 'dbname=player_data user=postgres host=127.0.0.1 password=mypassword' AS postgres (TYPE POSTGRES);")
如果我运行这个
r = self.conn.sql('''
INSERT INTO postgres.ranked.ranked_data
SELECT * FROM 'data/*.json';
''')
print(r)
它给了我这个错误
duckdb.duckdb.Error: Failed to copy data: ERROR: duplicate key value violates unique constraint "unique_row"
DETAIL: Key (leagueid, queuetype, tier, rank, leaguepoints)=(766896e1-2b75-450f-acd4-083d5ef60b55, RANKED_SOLO_5x5, DIAMOND, I, 50) already exists.
CONTEXT: COPY ranked_data, line 45
如果我添加一个
ON CONFLICT
声明
r = self.conn.sql('''
INSERT INTO postgres.ranked.ranked_data
SELECT * FROM 'data/*.json'
ON CONFLICT DO NOTHING;
''')
print(r)
它给了我这个错误
duckdb.duckdb.BinderException: Binder Error: There are no UNIQUE/PRIMARY KEY Indexes that refer to this table, ON CONFLICT is a no-op
所以根据duckdb,它无法插入,因为有约束但同时也没有约束。请帮助我让这变得有意义!
从这里开始:
https://duckdb.org/docs/extensions/postgres
postgres_execute 函数 postgres_execute 函数允许在 Postgres 中运行任意查询,包括更新数据库架构和内容的语句。
附加 'dbname=postgresscanner' AS postgres_db (TYPE POSTGRES); 调用 postgres_execute('postgres_db', '创建表 my_table (i INTEGER)');
警告 此功能仅在 DuckDB v0.10.1+ 上可用,使用最新的 Postgres 扩展。要升级您的扩展,请运行 FORCE INSTALL postgres;。
所以:
duckdb.connect()
con = duckdb.connect()
con.install_extension('postgres')
con.load_extension('postgres')
con.sql("ATTACH 'dbname=test user=postgres host=127.0.0.1' AS postgres (TYPE POSTGRES);")
con.sql("create table postgres.duckdb_test (id integer primary key, fld varchar)")
con.commit()
con.sql("insert into postgres.duckdb_test values (1, 'dog'), (2, 'cat')")
con.commit()
con.sql("""CALL postgres_execute('postgres', "insert into duckdb_test values (1, 'fish') ON CONFLICT DO NOTHING RETURNING id")""")
Out[29]:
┌─────────┐
│ Success │
│ boolean │
├─────────┤
│ 0 rows │
└─────────┘
Postgres 日志显示:
2024-05-13 10:09:40.048 PDT [16512] postgres@test LOG: statement: BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
insert into duckdb_test values (1, 'fish') ON CONFLICT DO NOTHING RETURNING id
2024-05-13 10:09:40.048 PDT [16512] postgres@test LOG: statement: COMMIT