PyMySQL 一次查询中的不同更新?

PyMySQL different updates in one query?

所以我有一个 python 脚本,它遍历大约 350,000 个数据对象,并且根据一些测试,它需要更新代表 MySQl 数据库中的每个对象的行.我也在使用 pymysql,因为我用它遇到的麻烦最少,尤其是在发送大型 select 查询时(select 带有 where column IN (....) 子句的语句可以包含 100,000+ 个值)。

由于每行的每次更新都可以不同,因此每个更新语句都是不同的。例如,对于一行,我们可能希望更新 first_name,但对于另一行,我们希望保持 first_name 不变,我们希望更新 last_name.

这就是为什么我不想使用 cursor.executemany() 方法,该方法接受一个通用更新语句,然后您将值提供给它,但是正如我提到的,每个更新都是不同的,因此只有一个通用更新声明并不真正适用于我的情况。我也不想通过网络单独发送超过 350,000 条更新语句。无论如何,我可以将所有更新语句打包在一起并立即发送吗?

我尝试将它们全部放在一个查询中并使用 cursor.execute() 方法,但它似乎没有更新所有行。

SQL #1: CREATE TABLE t 包含您可能需要更改的任何列。使它们全部 NULL(而不是 NOT NULL)。

SQL #2:对所有需要的更改进行批量 INSERT(或 LOAD DATA)。例如,如果仅更改 first_name,则填写 idfirst_name,但其他列为 NULL.

SQL#3-14:

UPDATE real_table
  JOIN t  ON t.id = real_table.id
  SET real_table.first_name = t.first_name
  WHERE t.first_name IS NOT NULL;
# ditto for each other column.

除#1 外的所有 SQL 都将耗时。而且,由于 UPDATE 需要构建撤消日志,它可能会超时或出现其他问题。如有必要,请参阅 a discussion of chunking

如有必要,使用COALESCE()GREATEST()IFNULL()等函数

质量UPDATEs通常意味着架构设计不佳。

(如果 Ryan 使用 'Answer' 而不是 'Comment',他可能应该得到 'bounty'。)

如果您可以将 "tests" 编码到 SQL 逻辑本身,那么您的最佳表现将是,这样您就可以将所有内容归结为少量的 UPDATE 语句。或者至少以这种方式完成尽可能多的工作,这样需要单独更新的行就更少了。

例如:

UPDATE tablename set firstname = [some logic]
WHERE [logic that identifies which rows need the firstname updated];

您对测试的描述不多,所以很难确定。但是您通常可以通过一些工作在您的 WHERE 子句中获得相当多的逻辑。

另一种选择是将您的逻辑放入存储过程中。您仍将进行 350,000 次更新,但至少它们不是全部 "going over the wire"。不过,我只会将其用作最后的手段;业务逻辑应尽可能保留在应用层,而存储过程会使您的应用程序的可移植性降低。