Лучший способ вставить несколько строк с помощью asyncpg
Я хочу вставить несколько строк и получить идентификаторы обратно с помощью asyncpg, я нашел два способа: 1: создать sql, как это
INSERT INTO films (code, title, did, date_prod, kind) VALUES
('B6717', 'Tampopo', 110, '1985-02-10', 'Comedy'),
('HG120', 'The Dinner Game', 140, DEFAULT, 'Comedy')
RETURNING id;
2: использовать подготовленный оператор для цикла for
values =(('B6717', 'Tampopo', 110, '1985-02-10', 'Comedy'),
('HG120', 'The Dinner Game', 140, DEFAULT, 'Comedy'))
stmnt = connection.prepare("INSERT INTO films (code, title, did, date_prod, kind) VALUES $1, $2, $3, $4, $5 RETURNING id")
for val in values:
stmnt.fetchval(*val)
какой путь я должен предпочесть в случае 100x раз с 700 000 строк, или есть какой-то способ объединить этот подход? я полностью зеленый, так что бросай в меня несколько помидоров
2 ответа
Если вам нужно использовать RETURNING
предложение для получения идентификаторов обратно, то следующий является наиболее эффективным способом вставки нескольких значений:
res = await conn.fetch('''
INSERT INTO films (code, title, did, date_prod, kind)
(SELECT
r.code, r.title, r.did, r.date_prod, r.kind
FROM
unnest($1::films[]) as r
)
RETURNING id
''', [
(None, 'B6717', 'Tampopo', 110, '1985-02-10', 'Comedy'),
(None, 'HG120', 'The Dinner Game', 140, None, 'Comedy')
])
Обратите внимание, что записи, которые вы передаете в качестве входных данных, должны соответствовать форме таблицы: PostgreSQL не поддерживает произвольные записи в качестве входных данных, поэтому вы должны использовать известный тип записи. Просто передайте столбцы, которые вы не вставляете, как None
и не включать их в SELECT
возвратный список. Этот метод также не позволяет вам полагаться на DEFAULT
, вы должны указать каждое вставленное значение явно.
asyncpg
обеспечивает executemany
способ вставить много строк.
statement = """INTO films (code,
title,
did,
date_prod,
kind) VALUES($1, $2, $3, $4, $5);"""
await connection.executemany(statement, values)
Если вам нужно использовать RETURNING
как вы позже упоминали, чтобы вернуть вставленные идентификаторы, этот ответ - путь.
Другой способ вставить много строк одновременно (при условии, что вам не нужны вставленные идентификаторы) - это использовать copy_records_to_table
метод.
data = [
("row", 1, "some data"),
("row", 2, "more data"),
]
await conn.copy_records_to_table('mytable', records=data)