Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Python脚本删除SQL数据库中的多个条目_Python_Sqlalchemy_Sql Delete - Fatal编程技术网

使用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

我不熟悉Python和SQL,但我需要在远程服务器上删除表中的多个条目。我还希望保留我得到的函数的输入结构,因为它在其他同事的代码中使用

我提出了一个解决方案,它的工作与下面介绍的类似。我故意避免使用任何类型的
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查询生成器,不需要字符串!(大部分)