不幸的是,psycopg2 文档没有提供有关如何使用命名参数执行多行插入的任何详细信息。
他们展示了这个例子:
cur.execute("""
INSERT INTO some_table (id, created_at, updated_at, last_name)
VALUES (%(id)s, %(created)s, %(created)s, %(name)s);
""",
{'id': 10, 'name': "O'Reilly", 'created': datetime.date(2020, 11, 18)}
)
但仅适用于单个项目。 我有以下代码,但每次我尝试运行该代码时都会遇到此异常:
cursor.execute(sql, values)\nTypeError: list indices must be integers or slices, not str"}
这就是我尝试执行插入的方式:
from dataclasses import dataclass
from typing import Dict, List
import psycopg2
@dataclass
class MyObject:
job_id: str
param_a: str
param_b: str
def to_dict(self) -> Dict[str, str]:
return {"job_id": self.job_id, "param_a": self.param_a, "param_b": self.param_b}
class DatabaseConnection:
"""
Wrapper class to create a postgress database connection.
Is a helper to open and close the connection.
"""
def __init__(self, database: str = "dbname") -> None:
self.__database = database
self.__connection = None
def __enter__(self):
self.__connection = psycopg2.connect(
database=self.__database,
user="user",
password="pasword",
host="host",
port="8000",
sslmode="require",
)
return self.__connection
def __exit__(self, exception_type, exception_value, exception_traceback):
if self.__connection:
self.__connection.close()
def insert_values_to_db(objects: List[MyObject]) -> bool:
try:
with DatabaseConnection() as connection:
cursor = connection.cursor()
sql = (
"INSERT INTO dbtable"
"(job_id, param_a, param_b) VALUES"
"(%(job_id)s, %(param_a)s, %(param_b)s);"
)
values = [obj.to_dict() for obj in objects]
cursor.execute(sql, values)
connection.commit()
except Exception as _:
return False
return True
我不确定如何使用命名参数同时插入多个项目。
不幸的是,psycopg2 文档没有提供有关如何使用命名参数执行多行插入的任何详细信息。
是的,有:
https://www.psycopg.org/docs/extras.html#fast-execution-helpers
psycopg2.extras.execute_values(cur,sql,argslist,模板=无,page_size = 100,fetch = False)
使用 VALUES 和一系列参数执行语句。
...
模板 –
要合并到 argslist 中的每个项目以组成查询的代码片段。
如果 argslist 项是序列,则它应包含位置占位符(例如“(%s, %s, %s)”或“(%s, %s, 42)”(如果有常量值...)。
如果 argslist 项是映射,则它应包含命名占位符(例如“(%(id)s, %(f1)s, 42)”)。 如果未指定,则假设参数是序列并使用简单的位置模板(即 (%s, %s, ...)),并使用 argslist 中第一个元素嗅探到的占位符数量。
所以使用
template="(%(job_id)s, %(param_a)s, %(param_b)s)" in
execute_values()`。