Пропустить строку в .txt import to postgresql - PullRequest
0 голосов
/ 25 апреля 2019

Я пытаюсь импортировать 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')

Несколько строк данных, которые я пытаюсь импортировать:

example1@example.com:123456
example2@example.com: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

Как мне обрабатывать строкикоторый не может быть импортирован?

Спасибо за любую помощь

1 Ответ

0 голосов
/ 26 апреля 2019

В вашей трассировке указан источник исключения в for line in reader:

File "import.py", line 45, in importData
    for line in reader:
_csv.Error: line contains NULL byte

и в этот момент вы не обрабатываете исключения. Как предполагает исключение, оно вызывается вашим экземпляром csv reader. Хотя вы, конечно, можете заключить цикл for в блок try-Кроме, ваш цикл все равно завершится, как только возникнет исключение.

Это исключение может быть вызвано тем, что файл имеет кодировку, отличную от используемой в вашей локали, что предполагается open(), если кодировка явно не указана:

В текстовом режиме, если кодировка не указана, используется кодировка зависит от платформы: locale.getpreferredencoding(False) вызывается получить текущую кодировку локали.

Принятый ответ в этом Q & A описывает решение для решения этой проблемы, при условии, что вы можете определить правильную кодировку для открытия файла. В разделе «Вопросы и ответы» также показаны некоторые подходы к тому, как избавиться от пустых байтов в файле перед передачей его читателю.

Вы также можете просто пропустить пустые строки вместо того, чтобы запускать их в свою БД, и обработать исключение, например,

for line in reader:
    if not line:
        continue
    try:
        [...]
...