【发布时间】:2014-10-03 14:31:30
【问题描述】:
我一直在使用 pyodbc 开展一个项目,该项目从我们的数据库中提取姓氏列表,然后从后续表中迭代地提取每个家庭的数据,并将其写入电子表格中。这是一个浓缩的版本,展示了这个想法。
def Run(Family):
names = []
con = pyodbc.connect("...")
cursor = con.cursor()
cursor.execute("SELECT DISTINCT ... ")
for item in cursor:
names.append(item[0])
#print(item[0], 1)
for name in names:
cursor.execute("SELECT DISTINCT <data> FROM <tables> WHERE name = ?", name)
for item in cursor:
#print(item[0], 2)
name = item[0]
age = item[1]
income = item[2]
etc...
<Write to spreadsheet>
我遇到的问题是循环似乎跳过了列表中的某个名称。在调查时,我发现第一个(注释的)打印语句确实打印了名称,但是在第二个打印语句之间的某个地方,它消失了。
奇怪的是,如果我在写入电子表格的位置下方放置另一个打印语句,名称又回来了,但由于它没有通过第二个光标,它的数据没有被拉出,所以电子表格只是显示该名称包含之前名称中的所有信息。
我一直在试图弄清楚发生了什么,但真的看不到任何会导致这种情况的东西。请让我知道任何想法或任何其他可能有用的信息。谢谢!
Update1:我按照您的建议修复了迭代器名称,但这并没有解决它遗漏名称的问题。正如我所指出的,并非每个名字都这样做,每次只有一个名字。
更新 2: 我还按照您的建议修复了查询,尽管在这种情况下 sql 注入不应该构成威胁,因为“名称”不是由用户输入,而是从另一个字段中提取的在同一个数据库中,该数据库由我团队的其他成员单独管理。
【问题讨论】:
-
您应该使用
cursor.execute('... name = ?', name)而不是cursor.execute('... name = ' + name)。 (可能需要根据后端将?更改为其他内容。请查看pyodbc的文档)。如果您不这样做,您的代码可能会受到 SQL 注入的影响。如果有人输入像''; DROP TABLE ...这样的名称,您将丢失运行代码的数据。 -
您可以尝试按照 docs 传递参数而不是构建 SELECT 字符串 -
cursor.execute("SELECT DISTINCT <data> FROM <tables> WHERE name = ?", name)。如下所述,从您的示例看来,name尚未分配 值