如何在使用LOAD LOCAL DATA INFILE时获取行ID?

时间:2016-05-30 12:41:50

标签: mysql sql-insert mysql-python

我有MySQL数据库,其中包含了从多个文件中插入的表格 LOAD DATA LOCAL INFILE ...声明。我将PRIMARY KEY ID设置为auto_increment。问题是,当我想只更新表的一部分时。

说我过去插入了file_1, file_2, file_3,现在我只想更新file_2。我想象伪工作流程中的过程

  1. 删除与file_2
  2. 相关的旧数据
  3. file_2
  4. 插入新数据

    但是,很难确定哪些数据最初来自file_2。为了找到答案,我想出了这个想法:

    当我插入数据时,我会记下我插入的行的ID,因为我使用的是auto_increment,我可以为每个文件注意from_id, to_id之类的内容。然后,当我只想更新file_x时,我会仅删除from_id <= id <= to_id的数据(其中from_id, to_idfile_x相关)。

    经过一些搜索后,我发现了@@identitylast_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?

1 个答案:

答案 0 :(得分:1)

如果您需要记住表格中每条记录的来源,那么您最好将信息存储在一个字段中。

我会在表格中添加src类型的新字段(TINYINT)并存储来源1 file_12的ID } file_2 aso)。我假设不会超过255个来源;否则使用SHORTINT作为其类型。

然后,当您需要更新从file_2导入的记录时,您有两个选择:

  1. 删除所有src = 2的记录,然后将新记录从文件加载到表中;这不是一个更新,它是一个替代品;
  2. 将新记录从文件加载到新表中,然后从中复制更新现有记录所需的值。
  3. 选项#1

    删除是一件容易的事:

    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但它可以有任何名称)可用于从您想要忽略的所有列中加载数据。

    选项#2

    第二个选项需要创建工作表,但它更灵活。它允许根据通常的WHERE条件仅更新部分行。但是,只有在使用从文件加载的值(使用或不包含src列)识别记录时,才能使用它。

    工作表(让它命名为table_w)包含您要从文件加载的列,并且是预先创建的。

    如果需要更新从file_2导入的行,您可以执行以下操作:

    1. 截断工作表(只是为了确保它不包含先前导入的任何剩余部分);
    2. 将数据从文件加载到工作表中;
    3. 加入工作表和table_1并根据需要更新table_1的记录;
    4. 截断工作表(清除当前导入)。
    5. 代码:

      # 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