【问题标题】:For loop appears to skip certain items in listFor 循环似乎跳过了列表中的某些项目
【发布时间】: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 &lt;data&gt; FROM &lt;tables&gt; WHERE name = ?", name)。如下所述,从您的示例看来,name 尚未分配

标签: python pyodbc openpyxl


【解决方案1】:

对于这部分:

for item in names:
    cursor.execute("SELECT DISTINCT <data> FROM <tables> WHERE name = " + name)
    for item in cursor:

我很确定你的意思

for name in names:
    cursor.execute("SELECT DISTINCT <data> FROM <tables> WHERE name = " + name)
    for item in cursor:

请注意,我将第一个迭代器从 item 更改为 name。你打电话给item

【讨论】:

    【解决方案2】:

    您的问题是在循环中使用变量名“item”,然后使用它的嵌套循环。尝试将项目重命名为类似的其他名称

    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 item in names:
            cursor.execute("SELECT DISTINCT <data> FROM <tables> WHERE name = " + item)
            for family_data in cursor:
                #print(family_data[0], 2)
                name = item
                age = family_data[1]
                income = family_data[2]
                etc...
    
            <Write to spreadsheet>
    

    【讨论】:

      【解决方案3】:

      谢谢大家。我发现问题实际上出在 SQL 语句中,而不是 Python 部分。问题系列中的值之一是 NULL,因为我是 SQL 新手,所以我只使用了“join”而不是“left join”,这会返回整个游标为空,而不仅仅是那个字段。

      【讨论】:

      • 它们也是你的python代码的问题。这不是真正的答案
      • 如果 python 中有问题,我可以修复它们,但它们不是导致问题的原因。这就是解决我遇到的问题的方法,因此它是提出问题的正确答案。
      • 好吧,但是这个问题和答案现在非常具体到你的确切数据库。即没有人会从查看此页面中学到任何东西
      猜你喜欢
      • 2012-05-30
      • 2021-01-26
      • 2022-07-07
      • 1970-01-01
      • 2021-10-10
      • 1970-01-01
      相关资源
      最近更新 更多