psycopg2:使用命名参数插入多行

问题描述 投票:0回答:1

不幸的是,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

我不确定如何使用命名参数同时插入多个项目。

python-3.x post psycopg2
1个回答
0
投票

不幸的是,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()`。

© www.soinside.com 2019 - 2024. All rights reserved.