我有一些存在于MS SQL服务器中的CRM数据,我必须每天转移到mysql。我有一些移动表的python-pandas,read_sql()和to_sql()脚本。执行一些upsert逻辑后,我遇到了重复的主键错误。我有来自CRM的GUID作为表的主键 - 在MySQL中它是varchar(64)数据类型。不确定触发重复警告的内容。
mysql_table:
library (tidyverse)
df <- tribble(
~ID, ~V1, ~V2,~V3,
'1', NA,1, NA,
'2', 1,1,NA,
'3', 1,NA,NA,
'4', NA,NA,1,
'5', 1,1,1,
'6',NA,NA,1,
'7',1,NA,1
)
(GUID更长,我缩短了示例) 我将基于修改日期的MS SQL中的所有新记录拉入MySQL中的临时表,该日期大于我当前的表。其中一些可能是新记录,有些可能是我当前表中已存在但已更新的记录。
mysql_temp_table:
df2 <- tribble(
~Var,~V1,~V2,~V3,
'V1',0,2,1,
'V2',2,0,1,
'V3',1,1,0
)
我想直接更换任何修改过的记录,所以我从mysql_table中删除了所有常用记录。在这个例子中,我想从mysql_table中删除Ben,以便它可以被来自mysql_temp_table的Ben替换:
GUID-PK Name favorite_number modifiedon
00000B9D... Ben 10 '2017-01-01'
000A82A5... Harry 9 '2017-05-15'
000A9896... Fred 5 '2017-12-19'
然后我想将整个临时表移动到复制表中:
GUID-PK Name favorite_number modifiedon
00000B9D... Ben 15 '2018-01-01'
000A82BB... John 3 '2018-03-15'
000A4455... Ray 13 '2018-04-01'
但这给了我一个错误:
DELETE FROM mysql_table WHERE GUID-PK IN (SELECT GUID-PK FROM mysql_temp_table)
我可以看到许多GUID以'000'开头,似乎这被解释为'0'。不应该在上面的Delete-IN语句中捕获它。我被困在下一步去哪里。提前致谢。
答案 0 :(得分:1)
我怀疑DELETE语句操作失败并出现错误。
这是因为短划线字符不是标识符中的有效字符。如果列名真的是GUID-PK
,则需要在SQL文本中正确转义,或者将其封装在反引号中(MySQL中的正常模式),或者sql_mode
包括ANSI_QUOTES
然后标识符可以用双引号括起来。
另一种可能性是temp_table
没有在GUID-PK
列上定义的PRIMARY或UNIQUE KEY约束,并且temp_table
中有多个行具有{{1}的相同值1}},导致INSERT中的重复键异常进入mysql_table。
另一个猜测(因为我们没有看到temp_table的定义)是列的顺序不同,因此GUID-PK
不按SELECT * FROM temp_table
中预期的顺序返回列。我通过显式列出INSERT的目标表和SELECT列表中的列来解决该问题。
鉴于GUID-PK列是唯一键,我倾向于避免使用两个单独的语句(DELETE后跟INSERT),只使用mysql_table
语句。
INSERT ... ON DUPLICATE KEY UPDATE
答案 1 :(得分:0)
您可能已禁用AUTOCOMMIT。
如果您在同一个TRANSACTION中执行这两个操作并且未启用AUTOCOMMIT,则第二个READ COMMITTED语句将失败。 INSERTS,UPDATES和DELETES使用READ COMMITTED Isolation Level
执行您正在对DELETE之前出现的数据集执行INSERT。你需要:
一个。在TRANSACTION中明确地提交您的DELETE
或
B中。将两个陈述拆分为单独的TRANSACTION
或
℃。可重启的AUTOCOMMIT
如果不是这种情况,则需要调查DELETE和INSERT语句的数据集,因为DELETE不会无声地失败。