前段时间,我问question有关处理带有特殊字符的.csv文件的问题。当时我有兴趣解决90%的案件,但现在我又回到了最后的10%。
与以前的设置基本相同:
代码如下:
Select(Function(c) ChechBoxesText(Convert.ToInt32(c.Tag))))
以上结果是,如果我通过本机编解码器传递另存为.CSV的Excel文件,则导入有效。但是,调用包含formatting ='utf-8'关键字arg的unicodecsv文件崩溃
该错误消息表明我沿线某处传递了错误类型的对象。这是我第一次尝试从UTF-8文件中读取一行时发生的情况
import csv
import unicodecsv
#<Lots of other declarations and initialization>
def _csv_dict(self, file,index_field, ScrubMe, **kwargs):
#some irrelevant initialization stuff here.
if 'formatting' in kwargs:
formatting = kwargs['formatting']
else:
formatting = None #cp1252 is OS default
with open(file, encoding=formatting, errors='ignore') as f: #newline = '',
if formatting == None:
reader = csv.DictReader(f, dialect = 'excel')
else: #assume for now UTF-8 is the only other supported format
reader = unicodecsv.DictReader(f, dialect = csv.excel)
for line in reader:
<do some stuff - it's mostly building dictionaries, but I
generally edit the data to only keep the stuff I care about and do a little
data transformation to standard formats >
根据我的阅读,UTF-8实际上是制表符分隔而不是逗号分隔,但是我“认为”它应该以相同的方式工作。
我觉得我可能已经弄糟了一些非常简单的东西,但是我花了很多时间寻找寻求帮助的合适方法。预先感谢您的任何建议。
答案 0 :(得分:0)
我要替换最初的答案,因为我正在进行很多事情,并且花了一段时间才将它们解开。
1)@lenz是正确的。在Python 3中,无需使用unicodecsv.DictReader。令我感到困惑的部分是实现上的差异。
a)对于来自Python 2的旧版unicodecsv.DictReader:
kw_args={'errors' : None}
with open(filename, 'rb', **kw_args) as file:
reader = unicodecsv.DictReader(file, dialect = csv.excel, encoding='utf_8_sig' )
b)对于Python 3 csv.DictReader
kw_args={'newline' : '','errors' : None,'encoding' : 'utf_8_sig'}
with open(filename, 'r', **kw_args) as file:
reader = csv.DictReader(file, dialect = csv.excel )
总结差异
2)因为我的UTF-8文件是Excel生成的,所以文件顶部具有utf_16_le样式的BOM。唯一适用于此的编码是“ utf_8_sig”。
3)因为我的输出文件被SQL Server下游读取,所以输出编解码器需要为“ utf_16_le”,否则SQL Server无法识别它。
4)另外,由于目标是SQL Server,因此我必须手动将BOM表插入文件顶部。
csvfile.write('\uFEFF')
writer.writeheader()
如果您在Excel中打开上述输出文件,它将不再位于列中,但是SQL Server(实际上是SSIS)现在知道如何读取该文件。
5)只是想和我多一点,有人在一些记录中有“ \ n”。使用Excel作为源和目标,这不是问题,但这是SSIS的问题。我的解决方案:
for r in record_list:
temp={}
for k,v in r.items():
if isinstance(v,str):
temp[k] = v.replace('\n',' ')
else:
temp[k] = v
writer.writerow(temp)