我有MySQL数据库,其中包含了从多个文件中插入的表格
LOAD DATA LOCAL INFILE ...
声明。我将PRIMARY KEY ID
设置为auto_increment。问题是,当我想只更新表的一部分时。
说我过去插入了file_1, file_2, file_3
,现在我只想更新file_2
。我想象伪工作流程中的过程
file_2
file_2
但是,很难确定哪些数据最初来自file_2
。为了找到答案,我想出了这个想法:
当我插入数据时,我会记下我插入的行的ID,因为我使用的是auto_increment,我可以为每个文件注意from_id, to_id
之类的内容。然后,当我只想更新file_x
时,我会仅删除from_id <= id <= to_id
的数据(其中from_id, to_id
与file_x
相关)。
经过一些搜索后,我发现了@@identity
和last_insert_id()
(see),但是,select last_insert_id()
后使用LOAD DATA LOCAL INFILE
我只得到一个id,而不是对应于数据的最大id,但是最后添加的(如定义的那样)。我使用
mysql.connnector
从Python连接到数据库
cur.execute("select last_insert_id();")
print(cur.fetchall())
# gives
# [(<some_number>,)]
那么,有没有办法,如何检索分配给使用上述LOAD DATA LOCAL INFILE...
语句导入的数据的所有(或至少是最小和最大)ID?
答案 0 :(得分:1)
如果您需要记住表格中每条记录的来源,那么您最好将信息存储在一个字段中。
我会在表格中添加src
类型的新字段(TINYINT
)并存储来源1
file_1
,2
的ID } file_2
aso)。我假设不会超过255个来源;否则使用SHORTINT
作为其类型。
然后,当您需要更新从file_2
导入的记录时,您有两个选择:
src = 2
的记录,然后将新记录从文件加载到表中;这不是一个更新,它是一个替代品; 删除是一件容易的事:
DELETE FROM table_1 WHERE src = 2
加载新数据并将src
的值设置为2
也很简单(documentation中对此进行了解释):
LOAD DATA INFILE 'file.txt'
INTO TABLE table_1
(column1, column2, column42) # Put all the columns names here
# in the same order the values appear in the file
SET src = 2 # Set values for other columns too
如果文件中有您不需要的列,则将其值加载到变量中,然后忽略变量。例如,如果文件中的第三列不包含您可以使用的有用信息:
INTO TABLE table_1 (column1, column2, @unused, column42, ...)
单个变量(我称之为@unused
但它可以有任何名称)可用于从您想要忽略的所有列中加载数据。
第二个选项需要创建工作表,但它更灵活。它允许根据通常的WHERE
条件仅更新部分行。但是,只有在使用从文件加载的值(使用或不包含src
列)识别记录时,才能使用它。
工作表(让它命名为table_w
)包含您要从文件加载的列,并且是预先创建的。
如果需要更新从file_2
导入的行,您可以执行以下操作:
table_1
并根据需要更新table_1
的记录; 代码:
# 1
TRUNCATE table_w;
# 2
LOAD DATA INFILE 'file.txt'
INTO TABLE table_w
(column_1, column_2, column 42); # etc
# 3
UPDATE table_1 t
INNER JOIN table_w w
ON t.column_1 = w.column_1
# AND t.src = 2 # only if column_1 is not enough
SET t.column_2 = w.column_2,
t.column_42 = w.column_42
# WHERE ... you can add extra conditions here, if needed
# 4
TRUNCATE TABLE table_w