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

时间:2016-02-01 20:02:55

标签: 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()方法,但它似乎不会更新所有行。

2 个答案:

答案 0 :(得分:5)

如果您可以对您的"测试进行编码,那么您的最佳表现就是"进入SQL逻辑本身,所以你可以把所有东西都归结为少数UPDATE语句。或者至少以这种方式尽可能多地完成,以便需要单独更新更少的行。

例如:

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

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

另一个选择是将您的逻辑放入存储过程。您仍然会进行350,000次更新,但至少他们并不是所有人都会通过电话进行更新#34;。不过,我会把它作为最后的手段。业务逻辑应尽可能保留在应用程序层中,并且存储过程使您的应用程序不那么便携。

答案 1 :(得分: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.

除#1之外的所有SQL都非常耗时。并且,由于UPDATE需要构建撤消日志,因此可能会超时或出现问题。如有必要,请参阅a discussion of chunking

如有必要,请使用COALESCE()GREATEST()IFNULL()等功能。

质量UPDATEs通常意味着糟糕的架构设计。

(如果Ryan跳入'答案'而不仅仅是'评论',他应该得到'赏金'。)