从python

时间:2019-05-06 14:29:16

标签: python regex csv amazon-redshift bonobo-etl

我目前正在从多个SQL Server数据库到AWS Redshift进行大规模数据迁移。我正在使用python + bonobos-etl来完成此任务,到目前为止,我对此感到非常满意。但是,在迁移一个特定的表时,我遇到了一个问题,即有特定字符无法转移到Redshift中。 Redshift错误如下:

Missing newline: Unexpected character 0x20 found at location 226

据我了解(尽管我可能错了),这是EOL字符的ASCII编码。

即使我删除有问题的行,有时也会在导入的数百万行中偶尔发现此错误,因此我想在数据提取期间解决此问题。

有问题的字符在我的.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 shell或正则表达式测试服务中。有什么快速简便的方法可以检查我的麻烦人物吗?谢谢。

1 个答案:

答案 0 :(得分:0)

所以我相信我已经弄清楚了我的问题。尽管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 / except块,现在我在其中用空字符串替换\x00,例如:myDict[str(k)] = re.sub('\x00', '', myDict[str(k)])

我的.csvs现在没有替换字符,因此我认为问题已解决。奇怪的是,AWS在实际0x20中将字符报告为x00,但是我不确定这是否是它们的错误,或者我是否误解了字符编码。谢谢所有提出建议的人,因为我只能通过您的指导来解决。我知道回答我自己的问题有点古怪,因此,如果这违反了StackOverflow准则,请随时结束此问题。谢谢。