给出以下模式:
CREATE TABLE parent (
parent_id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
last_updated TIMESTAMP DEFAULT NOW(),
UNIQUE(name)
);
CREATE TABLE child(
parent_id INT NOT NULL REFERENCES parent(parent_id),
data TEXT NOT NULL,
extra TEXT,
last_updated TIMESTAMP DEFAULT NOW(),
UNIQUE(data)
);
我有输入应该为父表中的每个插入在父表中产生N个插入,在子表中产生1个或多个插入。此外,此输入可能会被处理多次,并且不应导致其他行,而只会更新现有行。
这是一个简单的插入内容,显示了我要执行的操作:
WITH upserted_parent AS (
INSERT INTO parent (name)
VALUES ('parent1')
ON CONFLICT (name)
DO UPDATE SET last_updated = now()
RETURNING parent_id
) INSERT INTO child (
parent_id,
data,
extra
) VALUES (
(SELECT * FROM upserted_parent),
'data1',
'extra1'
), (
(SELECT * FROM upserted_parent),
'data2',
'extra2')
ON CONFLICT (data)
DO UPDATE SET extra = 'extra1', last_updated = now();
到目前为止,我一直在使用psycopg2的execute
传递sql字符串(用%(data)s
代替字符串)和参数字典(例如{'data': input['data']}
。这不再起作用当这些参数之一是列表时。
有没有一种方法可以在一次调用中完成这些插入操作?还是禁止N个调用,每个父插入插入一个?