如何使用可迭代和不可迭代参数在 psycopg2 中执行 SQL 查询
How to execute SQL query in psycopg2 with iterable and non-iterable parameters
我正在尝试使用带有两个参数的 psycopg2 在 PostgreSQL 数据库中执行删除查询:
person_id = 1
和
role_id_list = [(1,), (2,), (3,)]
因此在数据库中,具有特定 id 的人可以具有特定的“角色”,这些角色由整数元组列表指定。 role_id_list
是元组列表而不是整数列表的原因是因为这是我的另一个 SQL 查询的 return 格式。
无论如何,我想从我的 person_roles
table 中删除所有匹配项,其中 perdon_id = 1
和 role_id
在列表 role_id_list
[=25= 中]
因为我有一个可迭代对象作为参数,所以我检查了我是否应该使用 psycopg2 中的 executemany
-函数:
https://www.psycopg.org/docs/cursor.html#cursor.executemany
所以该函数采用可迭代作为参数,但是如果我像我在示例中那样具有不可迭代和可迭代参数怎么办?
我用以下函数试试运气:
def delete_person_roles(person_id, role_id_list):
sql = "DELETE FROM person_roles WHERE person_id = %s AND role_id = %s;"
conn = None
try:
# read database configuration
# connect to the PostgreSQL database
conn = psycopg2.connect(
host="localhost",
database="mydatabase",
user="myuser",
password="mypassword")
# create a new cursor
cur = conn.cursor()
# execute the DELETE statement
cur.executemany(sql, (person_id, role_id_list))
# commit the changes to the database
conn.commit()
# close communication with the database
cur.close()
except (Exception, psycopg2.DatabaseError) as error:
print(error)
finally:
if conn is not None:
conn.close()
如果我现在打电话:
delete_person_roles(person_id, role_id_list)
我收到消息:
'int' object does not support indexing
所以我的问题是: 是否可以在不使用 for
循环的情况下在 psycopg2 中同时传递可迭代和不可迭代参数?或者我应该简单地使用 for
循环并逐一删除?
我已经找到了解决方法。通过按以下方式编辑函数中的 SQL-查询:
sql = "DELETE FROM person_roles WHERE person_id = %s AND role_id = ANY(%s);"
然后简单地使用 execute
而不是 executemany
让一切正常。
所以这个函数有效:
def delete_person_roles(person_id, role_id_list):
sql = "DELETE FROM person_roles WHERE person_id = %s AND role_id = ANY(%s);"
conn = None
try:
# read database configuration
# connect to the PostgreSQL database
conn = psycopg2.connect(
host="localhost",
database="mydatabase",
user="myuser",
password="mypassword")
# create a new cursor
cur = conn.cursor()
# execute the DELETE statement
cur.execute(sql, (person_id, role_id_list))
# commit the changes to the database
conn.commit()
# close communication with the database
cur.close()
except (Exception, psycopg2.DatabaseError) as error:
print(error)
finally:
if conn is not None:
conn.close()
我正在尝试使用带有两个参数的 psycopg2 在 PostgreSQL 数据库中执行删除查询:
person_id = 1
和
role_id_list = [(1,), (2,), (3,)]
因此在数据库中,具有特定 id 的人可以具有特定的“角色”,这些角色由整数元组列表指定。 role_id_list
是元组列表而不是整数列表的原因是因为这是我的另一个 SQL 查询的 return 格式。
无论如何,我想从我的 person_roles
table 中删除所有匹配项,其中 perdon_id = 1
和 role_id
在列表 role_id_list
[=25= 中]
因为我有一个可迭代对象作为参数,所以我检查了我是否应该使用 psycopg2 中的 executemany
-函数:
https://www.psycopg.org/docs/cursor.html#cursor.executemany
所以该函数采用可迭代作为参数,但是如果我像我在示例中那样具有不可迭代和可迭代参数怎么办?
我用以下函数试试运气:
def delete_person_roles(person_id, role_id_list):
sql = "DELETE FROM person_roles WHERE person_id = %s AND role_id = %s;"
conn = None
try:
# read database configuration
# connect to the PostgreSQL database
conn = psycopg2.connect(
host="localhost",
database="mydatabase",
user="myuser",
password="mypassword")
# create a new cursor
cur = conn.cursor()
# execute the DELETE statement
cur.executemany(sql, (person_id, role_id_list))
# commit the changes to the database
conn.commit()
# close communication with the database
cur.close()
except (Exception, psycopg2.DatabaseError) as error:
print(error)
finally:
if conn is not None:
conn.close()
如果我现在打电话:
delete_person_roles(person_id, role_id_list)
我收到消息:
'int' object does not support indexing
所以我的问题是: 是否可以在不使用 for
循环的情况下在 psycopg2 中同时传递可迭代和不可迭代参数?或者我应该简单地使用 for
循环并逐一删除?
我已经找到了解决方法。通过按以下方式编辑函数中的 SQL-查询:
sql = "DELETE FROM person_roles WHERE person_id = %s AND role_id = ANY(%s);"
然后简单地使用 execute
而不是 executemany
让一切正常。
所以这个函数有效:
def delete_person_roles(person_id, role_id_list):
sql = "DELETE FROM person_roles WHERE person_id = %s AND role_id = ANY(%s);"
conn = None
try:
# read database configuration
# connect to the PostgreSQL database
conn = psycopg2.connect(
host="localhost",
database="mydatabase",
user="myuser",
password="mypassword")
# create a new cursor
cur = conn.cursor()
# execute the DELETE statement
cur.execute(sql, (person_id, role_id_list))
# commit the changes to the database
conn.commit()
# close communication with the database
cur.close()
except (Exception, psycopg2.DatabaseError) as error:
print(error)
finally:
if conn is not None:
conn.close()