使用kwargs psycopg2构建查询

时间:2017-05-02 21:04:40

标签: postgresql python-3.x 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'

如何在不进行字符串格式化或字符串构建的情况下完成此工作?

1 个答案:

答案 0 :(得分:0)

您应该将元组 dict 作为第二个参数传递给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规范,因此您必须更仔细地查看它。