【问题标题】:Most python(3)esque way to repeatedly SELECT from MySQL database大多数python(3)esque方式重复从MySQL数据库中选择
【发布时间】:2015-06-30 10:15:56
【问题描述】:

我有一个客户 ID 的 csv 文件 (CRM_id)。我需要从数据库的客户表中获取他们的主键(一个自动增量整数)。 (我无法保证 CRM_ids 的完整性,所以我选择不将其设为主键)。

所以:

customers = []
with open("CRM_ids.csv", 'r', newline='') as csvfile:
    customerfile = csv.DictReader(csvfile, delimiter = ',', quotechar='"', skipinitialspace=True)
    #only one "CRM_id" field per row
    customers = [c for c in customerfile]

到目前为止这么好?我认为这是最蟒蛇式的做法(但很高兴听到其他情况)。

现在是丑陋的代码。它有效,但我讨厌附加到列表,因为它必须为每个循环复制和重新分配内存,对吗?有没有更好的方法(预分配+枚举来跟踪索引浮现在脑海中,但也许有一种更快/更好的方法,巧妙地使用SQL,以免进行数千个单独的查询......)?

cnx = mysql.connector.connect(user='me', password=sys.argv[1], host="localhost", database="mydb")
cursor = cnx.cursor()
select_customer = ("SELECT id FROM customers WHERE CRM_id = %(CRM_id)s LIMIT 1;")
c_ids = []
for row in customers:
    cursor.execute(select_customer, row)
    #note fetchone() returns a tuple, but the SELECTed set
    #only has a single column so we need to get this column with the [0]
    c_ids.extend(cursor.fetchall())
    c_ids = [c[0] for c in c_ids]

编辑: 目的是获取列表中的主键,以便我可以使用它们从链接表中的其他 CSV 文件中分配一些其他数据(客户 id 主键是这些其他表的外键,并且分配算法会发生变化,所以它是最好能够灵活地在 python 中进行分配,而不是硬编码 SQL 查询)。我知道这听起来有点倒退,但“客户端”只适用于电子表格而不是 ERP/PLM,所以我必须自己为这个小应用程序建立“关系”。

【问题讨论】:

  • 您要查找的词是“pythonic”。
  • 你想完成什么?您似乎已将数据移入数据库,现在正尝试将新的 rowid 附加到 csv 文件中的旧数据。最终目标是什么?
  • 使用select id, CRM_id from customers 生成的交叉引用列表能否实现您的目的。

标签: python mysql csv


【解决方案1】:

改变你的查询以获得你想要的结果怎么样?

crm_ids = ",".join(customers)
select_customer = "SELECT UNIQUE id FROM customers WHERE CRM_id IN (%s);" % crm_ids

根据the manual,即使是数兆字节的查询,MySQL 也应该没问题;如果它是一个非常长的列表,您可以随时将其分解 - 保证两三个查询比几千个查询快得多。

【讨论】:

  • 啊,太好了,看起来不错。除了,我不应该 ORDER BY FIELD 以确保我以与传递 CRM_ids 相同的顺序返回 ids 吗?
  • 另外,我相信从 2.6 开始可以使用 str.format() 而不是 %。 (当我稍后重读此内容以用于更普遍的情况时,对我的提醒更多)
  • 最后,如果CRM_idVARCHAR,则可能需要"\",\"".join(customers 然后CRM_ids = "\"" + CRM_ids + "\"" 将每个字段用引号括起来作为字符串。
  • 如果您需要通过CRM_id 访问,我也只需SELECT 该字段 - 然后返回的每一行都将包含CRM_idid。跨度>
【解决方案2】:

如何将您的 csv 存储在字典而不是列表中:

customers = [c for c in customerfile]

变成:

customers = {c['CRM_id']:c for c in customerfile}

然后选择整个外部参照:

result = cursor.execute('select id, CRM_id from customers')

并将新的 rowid 添加为字典中的新条目:

for row in result:
    customers[row[1]]['newid']=row[0]

【讨论】:

  • 谢谢,这不是我目前需要做的,但是当我稍后重构代码时它会很有用。抱歉,我应该更清楚这个问题。
猜你喜欢
  • 1970-01-01
  • 2014-02-28
  • 2018-05-13
  • 2014-08-26
  • 1970-01-01
  • 2016-12-17
  • 2020-12-09
  • 2017-07-01
  • 2016-06-28
相关资源
最近更新 更多