Как вставить несколько строк в несколько таблиц? - PullRequest
0 голосов
/ 13 июня 2019

С учетом этой схемы:

    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 вызовов, по одному на каждую родительскую вставку?

...