【问题标题】:Python to SQL: list of listsPython 到 SQL:列表列表
【发布时间】:2011-08-19 19:53:05
【问题描述】:

我目前在将 python 列表导出到 mySQL DB 时遇到问题。 我正在使用 MySQLdb 并使用 executemany 命令。

例如,我有一个列表列表:

k1=[[['Bob', 'Alfred', 'Jen'],
['123 Elm Street', '55 Ninth Ave', '1 Paved Rd'],
[00123, 34565, 30094],
['Newark', 'Salinas', 'Los Angeles'],
['NJ', 'CA', 'CA']],[['Bob1', 'Alfred1', 'Jen1'],
['123 Elm Street1', '55 Ninth Ave1', '1 Paved Rd1'],
[001231, 345651, 300941],
['Newark1', 'Salinas1', 'Los Angeles1'],
['NJ1', 'CA1', 'CA1']]]

然后我尝试(在初始化光标和要使用的数据库之后):

cursor.executemany('''INSERT INTO addresses
                 (name, street, zipcode, city, state)
                 VALUES
                 (%s, %s, %s, %s, %s)''',zip(k1))

我得到一个错误:

 _mysql_exceptions.ProgrammingError: not enough arguments for format string

嗯,基本上,我想要列表 k1 到 mySQL db 表“地址”列表中的名称、街道、邮政编码、城市和州以及相应的字段条目。

如果有人能指出我正确的方向,那就太好了。

【问题讨论】:

  • 如果它看起来难看,不要道歉,而是阅读如何格式化事物。您使用的是重组文本语法。
  • 您的列表项每个包含三个条目,但您的格式字符串预期为五个。另一个问题是您的列表条目列表似乎代表列而不是行。
  • 保罗,没错。我确实看到了问题。我想做的是从列表列表中收集 5 个条目(即排序)。这不能使用“zip”吗?
  • 法尔马里,很抱歉。你能告诉我你做了什么来格式化列表吗?我确实尝试过缩进 4 个空格,但这没有用:虽然它适用于其他代码。
  • 压缩不是你的问题。 SQL 插入语句插入行,而不是列。如果要使用相同的 SQL,则需要重新排列数据结构。

标签: python mysql mysql-python


【解决方案1】:

如果你让你的数据结构看起来像这样:(不是格式化而是组织。你需要表示行而不是列来插入 SQL。)

[        
    ['Bob',     '123 Elm Street',  00123, 'Newark',     'NJ'],        
    ['Alfred',   '55 Ninth Ave',    34565, 'Salinas',   'CA'],
    ['Jen',     '1 Paved Rd',      30094, 'Los Angeles','CA']
]

您的 SQL INSERT 可能有工作的机会。

【讨论】:

    【解决方案2】:

    你的数据结构真的很尴尬。我假设您想将 k1 转换为:

    >>> sum([zip(*x) for x in k1], [])
    <<< 
    [('Bob', '123 Elm Street', 83, 'Newark', 'NJ'),
     ('Alfred', '55 Ninth Ave', 34565, 'Salinas', 'CA'),
     ('Jen', '1 Paved Rd', 30094, 'Los Angeles', 'CA'),
     ('Bob1', '123 Elm Street1', 665, 'Newark1', 'NJ1'),
     ('Alfred1', '55 Ninth Ave1', 345651, 'Salinas1', 'CA1'),
     ('Jen1', '1 Paved Rd1', 300941, 'Los Angeles1', 'CA1')]
    

    现在你可以执行许多操作了:

    sql = "INSERT INTO addresses (name, street, zipcode, city, state) VALUES (%s, %s, %s, %s, %s)"
    data = sum([zip(*x) for x in k1], [])
    cursor.executemany(sql, data)
    

    【讨论】:

      【解决方案3】:

      我认为您的意思是将 k1 中的每个列表(每个列表都包含几个列表)传递给 zip,如下所示:

      >>> [zip(*x) for x in k1]
      [[('Bob', '123 Elm Street', 83, 'Newark', 'NJ'), ('Alfred', '55 Ninth Ave', 34565, 'Salinas', 'CA'), ('Jen', '1 Paved Rd', 30094, 'Los Angeles', 'CA')], [('Bob1', '123 Elm Street1', 665, 'Newark1
      ', 'NJ1'), ('Alfred1', '55 Ninth Ave1', 345651, 'Salinas1', 'CA1'), ('Jen1', '1 Paved Rd1', 300941,   'Los Angeles1', 'CA1')]]
      >>> 
      

      还要注意,您的邮政编码应该是字符串,而不是数字,以保留前导零,并避免将它们误解析为您不想要的东西(参见那里的“83”邮政编码?它是 00123我相信)。

      【讨论】:

      • 是的,琼斯,这就是我想要的。非常感谢。添加外部“总和”可以解决问题(正如 zeekay 所建议的那样)
      【解决方案4】:

      我不认为这真的是一个 SQL 问题;在您尝试调用 executemany() 之前,让我们专注于以正确的形式获取数据。

      您的 k1 示例是一个包含 2 个列表的列表,每个列表也是一个列表列表,它们是名称/地址组件。所以你实际上有一个列表列表。我不知道列表的外层有什么意义,但内层似乎可以压缩。

      忽略那个外层,我认为你想要的是

      zip(*k1[0])
      

      这会为 k1 中的第一个元素产生看起来合理的结果。同样,我不知道在 k1[0] 和 k1[1] 中重复相同数据的意图是什么,所以我不会试图猜测您将如何处理 k1 中的其他元素。

      同样,在考虑如何将其与您的 SQL 数据库集成之前,请尝试在 python 解释器中使用它:

      >>> k1=[[['Bob', 'Alfred', 'Jen'],['123 Elm Street', '55 Ninth Ave', '1 Paved Rd'],[00123, 34565, 30094],['Newark', 'Salinas', 'Los Angeles'],['NJ', 'CA', 'CA']],[['Bob1', 'Alfred1', 'Jen1'],['123 Elm Street1', '55 Ninth Ave1', '1 Paved Rd1'],[001231, 345651, 300941],['Newark1', 'Salinas1', 'Los Angeles1'],['NJ1', 'CA1', 'CA1']]]
      >>> zip(k1)
      [([['Bob', 'Alfred', 'Jen'], ['123 Elm Street', '55 Ninth Ave', '1 Paved Rd'], [83, 34565, 30094], ['Newark', 'Salinas', 'Los Angeles'], ['NJ', 'CA', 'CA']],), ([['Bob1', 'Alfred1', 'Jen1'], ['123 Elm Street1', '55 Ninth Ave1', '1 Paved Rd1'], [665, 345651, 300941], ['Newark1', 'Salinas1', 'Los Angeles1'], ['NJ1', 'CA1', 'CA1']],)]
      >>> k1[0]
      [['Bob', 'Alfred', 'Jen'], ['123 Elm Street', '55 Ninth Ave', '1 Paved Rd'], [83, 34565, 30094], ['Newark', 'Salinas', 'Los Angeles'], ['NJ', 'CA', 'CA']]
      >>> k = k1[0]
      >>> zip(k)
      [(['Bob', 'Alfred', 'Jen'],), (['123 Elm Street', '55 Ninth Ave', '1 Paved Rd'],), ([83, 34565, 30094],), (['Newark', 'Salinas', 'Los Angeles'],), (['NJ', 'CA', 'CA'],)]
      >>> zip(k[0], k[1])
      [('Bob', '123 Elm Street'), ('Alfred', '55 Ninth Ave'), ('Jen', '1 Paved Rd')]
      >>> zip(k[0], k[1], k[2], k[3], k[4])
      [('Bob', '123 Elm Street', 83, 'Newark', 'NJ'), ('Alfred', '55 Ninth Ave', 34565, 'Salinas', 'CA'), ('Jen', '1 Paved Rd', 30094, 'Los Angeles', 'CA')]
      >>> zip(*k)
      [('Bob', '123 Elm Street', 83, 'Newark', 'NJ'), ('Alfred', '55 Ninth Ave', 34565, 'Salinas', 'CA'), ('Jen', '1 Paved Rd', 30094, 'Los Angeles', 'CA')]
      

      【讨论】:

      • 还是要处理00123变成83的问题。
      • @Dr.J:是的。使用列表推导来评估外层的解决方案([zip(*x) for x in k1])也更好。如果您想要的是对原始问题的字面回答。我试图提供一些关于 zip 实际处理这些数据的见解,引导展示如何正确使用它,以及如何理解和自学正在发生的事情。
      猜你喜欢
      • 2020-08-06
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      • 1970-01-01
      • 2012-08-07
      • 2015-11-23
      • 2014-06-24
      • 2021-11-13
      相关资源
      最近更新 更多