我正在尝试将5'000 .txt文件导入postgresql数据库。我的脚本运行正常,只要它没有到达不符合格式的行。例如,每个文件末尾都有一个新行,这也会导致脚本崩溃。
我试图处理异常但没有成功......
我的剧本:
import csv
import os
import sys
import psycopg2
conn = psycopg2.connect(
host="localhost",
database="demo",
user="demo",
password="123",
port="5432"
)
cur = conn.cursor()
maxInt = sys.maxsize
while True:
try:
csv.field_size_limit(maxInt)
break
except OverflowError:
maxInt = int(maxInt / 10)
def searchFiles(directory='', extension=''):
print('SEARCHING IN: ', directory)
filelist = []
extension = extension.lower()
for dirpath, dirnames, files in os.walk(directory):
for name in files:
if extension and name.lower().endswith(extension):
filelist.append(os.path.join(dirpath, name))
elif not extension:
print('FAILED TO READ: ', (os.path.join(dirpath, name)))
print('FINISHED FILE SEARCH AND FOUND ', str(len(filelist)), ' FILES')
return filelist
def importData(fileToImport):
with open(fileToImport, 'r') as f:
reader = csv.reader(f, delimiter=':')
for line in reader:
try:
cur.execute("""INSERT INTO demo VALUES (%s, %s)""", (line[0], line[1]))
conn.commit()
except:
pass
print('FAILED AT LINE: ', line)
print(conn.get_dsn_parameters())
cur.execute("SELECT version();")
record = cur.fetchone()
print("You are connected to - ", record)
fileList = searchFiles('output', '.txt')
counter = 0
length = len(fileList)
for file in fileList:
# if counter % 10 == 0:
print('Processing File: ', str(file), ', COMPLETED: ', str(counter), '/', str(length))
importData(str(file))
counter += 1
print('FINISHED IMPORT OF ', str(length), ' FILES')
我要导入的几行数据:
[email protected]:123456
[email protected]:password!1
我得到的错误:
File "import.py", line 66, in <module>
importData(str(file))
File "import.py", line 45, in importData
for line in reader:
_csv.Error: line contains NULL byte
我应该如何处理无法导入的行?
谢谢你的帮助
您的回溯显示for line in reader
中的异常来源:
File "import.py", line 45, in importData
for line in reader:
_csv.Error: line contains NULL byte
并且您不会在那时处理异常。例外情况表明,它是由您的csv阅读器实例引发的。虽然你当然可以将你的for循环包装在try-except块中,但是一旦异常提升,你的循环仍然会结束。
此异常可能是由文件具有与您的语言环境不同的编码引起的,如果没有明确提供编码,则由open()
假设:
在文本模式下,如果未指定编码,则使用的编码取决于平台:调用
locale.getpreferredencoding(False)
以获取当前的区域设置编码。
this Q&A中接受的答案概述了解决这个问题的解决方案,前提是您可以识别正确的编码以打开文件。问答还展示了在将文件交给读者之前如何摆脱文件中的NULL字节的一些方法。
您可能还想简单地跳过空行而不是将它们发送到您的数据库并处理异常,例如
for line in reader:
if not line:
continue
try:
[...]