我目前正在通过直接读取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 |
有人可以告诉我如何实现上述目标。
答案 0 :(得分:2)
您的代码存在(至少)两个问题:
逐行迭代文本文件将永远不会返回空字符串(len(line)==0
),除非在文件末尾 编辑:甚至没有在Python的标准文件迭代器的文件末尾。这是因为返回的行总是包含行尾字符,即使是空行也是如此。尝试if len(line.strip())>0
检查包含空格和EOL字符以外的内容的行。
修复后,您遇到了一个更大的问题:您的代码会尝试立即加载整个文件,而不是加载单个行。您可能需要重新构建它以使用标准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 module和delimiter = '\t'
其次,正如@dan所说,为什么要尝试插入整个文件而不是逐行进行?