使用python查询数据库的最佳实践

时间:2018-07-10 16:04:09

标签: python mysql-python cx-oracle

下面是代码。在迭代字典时,代码多次查询。多次执行查询或对数据库执行Ping操作是最佳做法吗?

import cx_Oracle
connDev = 'username/password@hostname:port/service'
connDev = cx_Oracle.connect(connDev)

cursor = connDev.cursor()

d = {'2006': '20170019201',
    '2006172': '2017000002',
    '200617123': '200003'
}

for key,value in d.items():
    cursDev.execute('SELECT columnName from tableName where columnName={}'.format(key))
    if len(cursDev.fetchall())!=0:
        # cursDev.execute('UPDATE tableName SET columnName= {0} WHERE columnName= {1} '.format(value, key))

    else:
        continue

connDev.commit()
cursDev.close()
connDev.close()

2 个答案:

答案 0 :(得分:0)

您可以运行一个查询并获得所有内容:

cursDev.execute(
    'SELECT columnName FROM tableName WHERE columnName IN ({})'.format(
        ','.join(':p{}'.format(n) for n in range(len(d))),
    {'p{}'.format(n): k for n, k in enumerate(d)}
)

或直接运行更新-如果找不到该行,它们将不执行任何操作:

for k, v in d.items():
    cursDev.execute(
        'UPDATE tableName SET columnName = {} WHERE columnName = :value',
        {'value': v}
    )

请注意,两个示例都在使用参数化查询-数据与查询分开传递,并且数据库的工作是进行参数插值-这样除使性能更好外,还使您摆脱了报价地狱并自动防止注入。

代码使用:value个命名型参数占位符,因为cx_Oracle使用的是占位符-请参见documentation on cx_Oracle.paramstyle

答案 1 :(得分:0)

对于这样的“批处理”更新,executemany()调用将是最有效的方法。

正如@nosklo所指出的,SELECT调用不是必需的-它们只需要时间。而且,使用executemany(),您无需重复进行execute()的呼叫,这又是一个节省。

来自samples/ArrayDMLRowCounts.py

# delete the following parent IDs only
parentIdsToDelete = [20, 30, 50]

print("Deleting Parent IDs:", parentIdsToDelete)
print()

# enable array DML row counts for each iteration executed in executemany()
cursor.executemany("""
        delete from ChildTable
        where ParentId = :1""",
        [(i,) for i in parentIdsToDelete],
        arraydmlrowcounts = True)

# display the number of rows deleted for each parent ID
rowCounts = cursor.getarraydmlrowcounts()
for parentId, count in zip(parentIdsToDelete, rowCounts):
    print("Parent ID:", parentId, "deleted", count, "rows.")

有关更多示例,请参见Efficient and Scalable Batch Statement Execution in Python cx_Oracle,包括那些具有多个绑定的示例。

[绝不(特殊情况除外)通过串联字符串来构建SQL语句。这是一个安全漏洞,也可能导致性能下降。始终使用绑定变量]