使用Python脚本删除SQL数据库中的多个条目
我不熟悉Python和SQL,但我需要在远程服务器上删除表中的多个条目。我还希望保留我得到的函数的输入结构,因为它在其他同事的代码中使用 我提出了一个解决方案,它的工作与下面介绍的类似。我故意避免使用任何类型的使用Python脚本删除SQL数据库中的多个条目,python,sqlalchemy,sql-delete,Python,Sqlalchemy,Sql Delete,我不熟悉Python和SQL,但我需要在远程服务器上删除表中的多个条目。我还希望保留我得到的函数的输入结构,因为它在其他同事的代码中使用 我提出了一个解决方案,它的工作与下面介绍的类似。我故意避免使用任何类型的executemany()方法,因为(如果我没有弄错的话)它们可能非常慢 import sqlalchemy as sa import urllib def delete_rows(tablename, colnames, data): """ tablename - n
executemany()
方法,因为(如果我没有弄错的话)它们可能非常慢
import sqlalchemy as sa
import urllib
def delete_rows(tablename, colnames, data):
"""
tablename - name of db table with dbname. like RiskData..factors
colnames - column names to use as keys in deletion
data - a list of tuples, a tuple per row, number of elements in each
tuple must is the same as number of column names
"""
# Connection details
engine = sa.create_engine("mssql+pyodbc://some_server")
connection = self.engine.connect()
# Data has to be a list - throw an exception if it is not
if (not (type(data) is list)):
raise Exception('Data must be a list');
# assemble one long query statement
query = "DELETE " + tablename + " WHERE "
query_dp = "or (" + " = '{}' and ".join(colnames) + "= '{}') "
query_tail = ""
for record_entries in data:
query_tail += query_dp.format(*record_entries)
query += query_tail[3:-1]
connection.execute(query)
connection.close()
我想问一下,对于大量数据,此解决方案是否效率低下且速度缓慢?如果是这样的话,还有什么更优雅的解决方案呢?不知道速度,但就优雅而言。由于您已经在使用SQLAlchemy,因此可以利用其查询构建功能:
def delete_rows(tablename, colnames, data):
"""
tablename - name of db table with dbname. like RiskData..factors
colnames - column names to use as keys in deletion
data - a list of tuples, a tuple per row, number of elements in each
tuple must is the same as number of column names
"""
# Data has to be a list - throw an exception if it is not
if not isinstance(data, list):
raise Exception('Data must be a list');
# Connection details
engine = sa.create_engine("mssql+pyodbc://some_server")
# Create `column()` objects for producing bindparams
cols = [sa.column(name) for name in colnames]
# Create a list of predicates, to be joined with OR
preds = []
for record_entries in data:
pred = sa.and_(*[c == e for c, e in zip(cols, record_entries)])
preds.append(pred)
# assemble one long query statement
query = sa.table(tablename).delete().where(sa.or_(*preds))
with engine.begin() as connection:
connection.execute(query)
executemany()
是否慢取决于正在使用的DB-API驱动程序。如果是pyodbc
,但是。您在DELETE
语句中匹配了多个列?如果我给data=1和columns=['id','street\u num']
怎么办?它会删除id=1和street_num=1的所有行吗?这真的是你想要的吗?使用ORM不是更好吗?例如,Django?@hansaplast,如果我的问题缺少一些细节,我很抱歉。我正在尝试删除条目。如果尝试您建议的输入,则会发生错误。如果假设我使用像data=[(1,2)、(3,4)]
和colnames=['id','street']
这样的输入,那么它将删除两行(id=1,street=2)和(id=3,street=4)在我看来,性能的真正问题是“多久一次”、“多少次”和“什么RDBMS”。出于对一切神圣事物的热爱,请不要使用字符串格式将值传递给查询。这就是占位符/bindparams的用途。将查询及其参数分别传递给execute()
。换句话说,不要将数据视为代码。其他人也可能这么做。。。另外,您正在使用SQLAlchemy,它是一个优秀的Python查询生成器,不需要字符串!(大部分)