使用 asyncpg 插入多行的最佳方法
Best way to insert multiple rows with asyncpg
我想插入多行并使用 asyncpg 取回 ID,我找到了两种方法:
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 , , , , RETURNING id")
for val in values:
stmnt.fetchval(*val)
如果 700 000 行 100 倍,我必须更喜欢哪种方式,或者有某种方式可以结合这些方法?
我完全变绿了,所以给我扔些西红柿
asyncpg
提供了 executemany
方法来插入多行。
statement = """INSERT INTO films (code,
title,
did,
date_prod,
kind) VALUES(, , , , );"""
await connection.executemany(statement, values)
如果您需要使用 RETURNING
,正如您稍后提到的 return 插入的 ID, 是正确的选择。
如果需要使用RETURNING
子句取回ids,那么下面是插入多个值最高效的方式:
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(::films[]) as r
)
RETURNING id
''', [
(None, 'B6717', 'Tampopo', 110, '1985-02-10', 'Comedy'),
(None, 'HG120', 'The Dinner Game', 140, None, 'Comedy')
])
请注意,您作为输入传递的记录 必须 对应于 table 的形状:PostgreSQL 不支持任意记录作为输入,因此您必须使用已知的记录类型。只需将您未插入的列作为 None
传递,并且不要将它们包含在 SELECT
return 列表中。此方法也不允许您依赖 DEFAULT
,您必须明确指定每个插入的值。
另一种一次插入多行的方法(假设您不需要插入的 ID)是使用 copy_records_to_table
方法。
data = [
("row", 1, "some data"),
("row", 2, "more data"),
]
await conn.copy_records_to_table('mytable', records=data)
我想插入多行并使用 asyncpg 取回 ID,我找到了两种方法: 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 , , , , RETURNING id")
for val in values:
stmnt.fetchval(*val)
如果 700 000 行 100 倍,我必须更喜欢哪种方式,或者有某种方式可以结合这些方法? 我完全变绿了,所以给我扔些西红柿
asyncpg
提供了 executemany
方法来插入多行。
statement = """INSERT INTO films (code,
title,
did,
date_prod,
kind) VALUES(, , , , );"""
await connection.executemany(statement, values)
如果您需要使用 RETURNING
,正如您稍后提到的 return 插入的 ID,
如果需要使用RETURNING
子句取回ids,那么下面是插入多个值最高效的方式:
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(::films[]) as r
)
RETURNING id
''', [
(None, 'B6717', 'Tampopo', 110, '1985-02-10', 'Comedy'),
(None, 'HG120', 'The Dinner Game', 140, None, 'Comedy')
])
请注意,您作为输入传递的记录 必须 对应于 table 的形状:PostgreSQL 不支持任意记录作为输入,因此您必须使用已知的记录类型。只需将您未插入的列作为 None
传递,并且不要将它们包含在 SELECT
return 列表中。此方法也不允许您依赖 DEFAULT
,您必须明确指定每个插入的值。
另一种一次插入多行的方法(假设您不需要插入的 ID)是使用 copy_records_to_table
方法。
data = [
("row", 1, "some data"),
("row", 2, "more data"),
]
await conn.copy_records_to_table('mytable', records=data)