使用 kwargs psycopg2 构建查询

building a query with kwargs psycopg2

我正在尝试动态构建查询并使用 psycopg2 包执行。我的查询如下所示

def get_employees_for_dept(dept_id):
    sql = '''SELECT 
           emp.FirstName,
           emp.LastName,
           dep.DepartmentName
        FROM Employee emp
        JOIN Department dep
        ON
          dp.EmployeeID = emp.Id
        WHERE
          dp.Id = :dept_id''';
return query.execute(sql, dept_id=dept_id)

现在我在查询脚本中的执行方法如下所示:

def execute(sql, **kwargs):
     with closing(psycopg2.connect(dbname=config.instance().db_name,
                              user=config.instance().db_user,
                              password=config.instance().db_password,
                              host=config.instance().db_host,
                              port=config.instance().db_port)) as conn:
       with closing(conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)) as cursor:
       cursor.execute(sql, **kwargs)
       return cursor.fetchall()

现在,当我 运行 这段代码时,我得到一个错误

cursor.execute(sql, **kwargs)
TypeError: execute() got an unexpected keyword argument 'user_id'

如何在不进行字符串格式化或字符串生成器的情况下完成这项工作?

您应该将 tupledict 作为第二个参数传递给 execute method,而不是 参数列表

但是当您执行 fun(sql, **kwargs) 时,您实际上展开了容器:fun(sql, a=5, b="ten", ...)

这是一个小例子:

def add_row(*args): # takes multiple arguments
    cur.execute("""
    INSERT INTO my_table (id, value)
    VALUES (%s, %s)
    """, args) # args is a tuple

my_args = (1, "some")
add_row(*my_args)
add_row(*(1, "some"))
add_row(1, "some")


def add_row(**kwargs): # takes multiple arguments
    cur.execute("""
    INSERT INTO my_table (id, value)
    VALUES (:a, :b)
    """, kwargs) # kwargs is a dict

my_kwargs = {"a":1, "b":"some"}
add_row(**my_kwargs)
add_row(**{"a":1, "b":"some"})
add_row(a=1, b="some")

阅读 here 关于向 sql 注入值的简要说明。由于 psycopg2 实现了 Python 数据库 API 规范,因此您必须更仔细地查看它。