Снятие ' ' со строки в питоне - PullRequest
0 голосов
/ 06 мая 2019

В настоящее время я нахожусь в процессе масштабной миграции данных из нескольких баз данных SQL Server в AWS Redshift.Я использую python + bonobos-etl для этой задачи, и до сих пор доволен этим.Однако при переносе одной конкретной таблицы я столкнулся с проблемой, в которой есть определенный символ, который нельзя перенести в Redshift.Ошибка Redshift выглядит следующим образом:

Missing newline: Unexpected character 0x20 found at location 226

Насколько я понимаю (хотя я могу ошибаться), это кодировка ASCII для символа EOL.

Даже если я удаляю строку, о которой идет речь, эту ошибку иногда можно найти в миллионах импортируемых мной строк, поэтому я хотел бы решить эту проблему во время извлечения данных.

Появляется рассматриваемый символв моем .csvs как:

Когда я просматриваю его в диспетчере SQL Server, это вообще не отображается.

Вот моя функция очистки данных (по общему признанию, немного беспорядочная):

def transform(row, **kwargs):
    """Placeholder, change, rename, remove... """
    global commitCounter
    print(commitCounter)
    commitCounter += 1

    for myDict in row:

        for k,v in myDict.items():

            myDict[str(k)] = re.sub(' +', ' ', str(v)).strip()

            if myDict[str(k)] == "None":
                myDict[str(k)] = None

            try: myDict[str(k)] = re.sub('<[^>]*>', '', myDict[str(k)]).replace("\n", "").replace("\t", "").replace("\r", "").replace("|", "")
            except: pass

            try: 
                myDict[str(k)] = re.sub(r'[^\x00-\x7F]+',' ', myDict[str(k)])
            except: pass

            try:
                datetime.datetime.strptime(myDict[str(k)],'%Y-%m-%d %H:%M:%S.%f')
                myDict[str(k)] = myDict[str(k)].rpartition('.')[0]
            except: pass

        yield myDict

У меня сложилось впечатление, что эта строка в коде специально решит проблему:

myDict[str(k)] = re.sub(r'[^\x00-\x7F]+',' ', myDict[str(k)])

Но это явно не так.У меня проблемы с игрой с регулярным выражением, чтобы решить эту проблему, так как я не могу скопировать / вставить символ в оболочку python или в службу тестирования регулярных выражений.Есть ли быстрый и простой способ проверить мой проблемный характер?Спасибо.

1 Ответ

0 голосов
/ 07 мая 2019

Так что я думаю, что понял свою проблему. Хотя AWS Redshift сообщал о проблеме как Missing newline: Unexpected character 0x20 found at location 226, после преобразования строки в байтовую строку я обнаружил, что фактическое значение неправильно кодированной строки было: x00. Теперь имеет смысл, почему myDict[str(k)] = re.sub(r'[^\x00-\x7F]+',' ', myDict[str(k)]) не будет правильно отфильтровывать символ, поскольку \x00 находится в допустимом диапазоне. Вместо этого я добавил еще один блок try / исключением, где теперь заменяю \x00 пустой строкой, например: myDict[str(k)] = re.sub('\x00', '', myDict[str(k)])

Мои .csvs теперь лишены заменяющего символа, поэтому я считаю, что проблема решена. Странно, что AWS сообщил о символе как 0x20, когда он был на самом деле x00, но я не уверен, является ли это ошибкой с их стороны или я неправильно понимаю кодировку символов. Спасибо всем, кто прокомментировал предложения, так как я смог понять это только под вашим руководством. Я знаю, что мне немного неудобно отвечать на мой собственный вопрос, поэтому, если это идет вразрез с рекомендациями StackOverflow, не стесняйтесь закрыть этот вопрос. Спасибо.

...