PyMySQL在一个查询中有不同的更新?

Mo.*_*Mo. 13 python mysql pymysql

所以我有一个python脚本,它通过大约350,000个数据对象,并且根据一些测试,它需要更新一行代表MySQl数据库中每个对象.我也使用pymysql,因为我遇到的问题最少,特别是在发送大型选择查询时(select语句where column IN (....)包含可能包含100,000+以上的值).

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

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

我尝试在一个查询中使用它们并使用该cursor.execute()方法但它似乎并不更新所有行.

小智 5

如果您可以将"测试"编码到SQL逻辑本身中,那么您的最佳表现就是如此,因此您可以将所有内容都归结为少数UPDATE语句.或者至少以这种方式尽可能多地完成,以便需要更少的行单独更新.

例如:

UPDATE tablename set firstname = [some logic]
WHERE [logic that identifies which rows need the firstname updated];
Run Code Online (Sandbox Code Playgroud)

你没有详细描述你的测试,所以很难确定.但是通常可以通过一些工作在WHERE子句中获得相当多的逻辑.

另一种选择是将您的逻辑放入存储过程.你仍然会做350,000次更新,但至少他们并非都是"通过网络".不过,我会将此作为最后的手段使用; 业务逻辑应尽可能保留在应用程序层中,并且存储过程使您的应用程序不那么可移植.


Ric*_*mes 4

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.
Run Code Online (Sandbox Code Playgroud)

除了 #1 之外的所有 SQL 都将非常耗时。而且,由于UPDATE需要构建撤消日志,因此可能会超时或出现其他问题。如有必要,请参阅分块的讨论。

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

质量UPDATEs通常意味着糟糕的模式设计。

(如果瑞安跳出来给出一个“答案”而不仅仅是一个“评论”,他可能应该得到“赏金”。)