检查tsv文件中的空行,而不是为该空行执行mysql插入

时间:2014-06-17 03:29:17

标签: python mysql

我目前正在通过直接读取tsv文件来执行mysql插入。我现在遇到的问题是,当tsv文件中有空行时,数据库中会插入NULL值。

我编写了以下代码片段来逐行读取整个TSV文件,如果该行不为空,则只进行插入。

with open('file.tsv','r+w') as file:
    for line in file:
      if len(line)>0:
        #upload to DB
        conn = connect_db()
        cursor = conn.cursor()
        try:
          cursor.execute("LOAD DATA LOCAL INFILE "file.tsv" INTO TABLE abcd FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n' (@col1,@col2,@col3) set a=@col1,b=@col2,grid=@col3,date='"+date+"', pipeline='"+pipeline_name+"'")

          conn.close()
        except:
          print (cursor._last_executed)
          raise

从TSV文件中读取错误的Mysql输出 -

13 | 2014-06-16 | apollo   | PT   |           380 |              316 |
| 14 | 2014-06-16 | apollo   |      |             0 |             NULL |

所需的Mysql输出 -

13 | 2014-06-16 | apollo   | PT   |           380 |              316 |
13 | 2014-06-17 | apollo   | PT   |           350 |              312 |

有人可以告诉我如何实现上述目标。

2 个答案:

答案 0 :(得分:2)

您的代码存在(至少)两个问题:

  1. 逐行迭代文本文件将永远不会返回空字符串(len(line)==0,除非在文件末尾 编辑:甚至没有在Python的标准文件迭代器的文件末尾。这是因为返回的行总是包含行尾字符,即使是空行也是如此。尝试if len(line.strip())>0检查包含空格和EOL字符以外的内容的行。

  2. 修复后,您遇到了一个更大的问题:您的代码会尝试立即加载整个文件,而不是加载单个行。您可能需要重新构建它以使用标准SQL INSERT语句而不是MySQL的LOAD DATA扩展名。

    最终结果应如下所示:

    db = ...
    cur = db.cursor()
    
    for line in f:
      if len(line.strip()) > 0:
        # tab-separated, right?
        fields = line.strip().split('\t')
        cursor.execute("INSERT INTO table_foo (a,b,c) VALUES (%s,%s,%s)", fields)
    

答案 1 :(得分:0)

打开文件的方式是,由于EOL字符,空行的长度等于1。更好的方法是使用Python CSV moduledelimiter = '\t'

其次,正如@dan所说,为什么要尝试插入整个文件而不是逐行进行?