在平面文件中插入SSIS中的unicode字符串

时间:2015-12-07 15:29:34

标签: python azure unicode ssis etl

我有一个项目,我使用Python脚本从各种API(Google Analytics,Facebook,Instagram等)收集数据。我将收集的数据写入平面文件,然后使用SSIS从文件中提取数据,执行一些ETL工作,然后插入到我们的数据仓库中。

我遇到的问题是使用Unicode值,看起来它们可能无法正确编码/解码,并且数据库中插入的字符与实际插入的字符不同。这是涉及的过程:

我使用csv模块编码数据值并写入文件:

import csv

with open('{0}{1}.txt'.format(file_path, file_name), 'ab+') as f:
    writer = csv.writer(f, delimiter='\t')
    try:
        writer.writerow(data['name'].encode('utf-8'))
    except Exception, ex:
        logging.exception(ex)

当我在Sublime Text等文本编辑器中打开文件时,所有unicode字符都正确显示。

完成所有数据写入文件后,我开始使用SSIS收集它。在SSIS中,我有一个平面文件源任务,可以提取数据。我已将连接管理器中“名称”列的数据类型定义为DT_WSTR (Length 4000)。平面文件连接的代码页是65001 (UTF-8)

我写的目标数据库是一个排序为SQL_Latin1_General_CP1_CI_AS的SQL Azure数据库。目标数据库列定义为nvarchar(max)。如果我尝试使用相同的排序规则写入常规SQL Server数据库,结果是相同的。

我在这里做错了什么?我收集了许多表情符号类型的字符,并不在乎,重要的是重音和非英语字符。如果我需要提供更多细节或其他任何内容,请告诉我。

1 个答案:

答案 0 :(得分:0)

根据您的描述,我查看了有关“Integration Services的国际注意事项”(https://msdn.microsoft.com/en-us/library/ms141186(v=sql.90).aspx)的文档,并为Python编码/解码制作了示例代码。

我认为代码data['name']不需要由UTF-8编码,因为默认情况下以二进制模式从文件读取数据是使用Python中的charset ISO-8859-1(Latin-1)。 / p>

作为参考,以下是我的实验代码,用于编码/解码下面的txt文件中的数据,其中包含UTF-8中的ISO-8859-1codecs以及方法encode('<charset>')。< / p>

名为input.txt

的txt文件中的数据
  

КатеринаАлександровна

import codecs

iso8859_1c = codecs.lookup('iso-8859-1')
utf8c = codecs.lookup('utf-8')

fpw = open('output.txt', 'wb')

fpr = open('input.txt', 'rb')
origin = fpr.readline()
print "Origin>", origin
print (bytearray(origin), )
print
fpw.write('Origin>')
fpw.write(origin)
fpw.write('\n')

fpr.close()

dec_iso8859_1, n = iso8859_1c.decode(origin)
print 'ISO-8859-1 decoding>', dec_iso8859_1, n
print (dec_iso8859_1, n)
print 'UTF-8 encoding ISO-8859-1>', dec_iso8859_1.encode('utf-8')
print 'ISO-8859-1 encoding ISO-8859-1>', dec_iso8859_1.encode('iso-8859-1')
print
fpw.write('UTF-8 encoding ISO-8859-1: dec_iso8859_1.encode("utf-8")>')
fpw.write(dec_iso8859_1.encode('utf-8'))
fpw.write('\n')

dec_utf8, n = utf8c.decode(origin)
print 'UTF-8 decoding>', dec_utf8, n
print (dec_utf8, n)
print 'UTF-8 encoding UTF-8>', dec_utf8.encode('utf-8')
# Error for code below: 'latin-1' codec can't encode characters in position 0-7: ordinal not in range(256)
# print 'ISO-8859-1 encoding UTF-8>', dec_utf8.encode('iso-8859-1')
print
fpw.write('UTF-8 encoding UTF-8: dec_utf8.encode("utf-8")>')
fpw.write(dec_utf8.encode('utf-8'))
fpw.write('\n')

enc_utf8_iso8859_1, n = utf8c.encode(dec_iso8859_1)
print 'UTF-8 encoding ISO-8859-1>', enc_utf8_iso8859_1, n
print (enc_utf8_iso8859_1, n)
print
fpw.write('UTF-8 encoding ISO-8859-1>')
fpw.write(enc_utf8_iso8859_1)
fpw.write('\n')

enc_iso8859_1_iso8859_1, n = iso8859_1c.encode(dec_iso8859_1)
print 'ISO-8859-1 encoding ISO-8859-1>', enc_iso8859_1_iso8859_1, n
print (enc_iso8859_1_iso8859_1, n)
fpw.write('ISO-8859-1 encoding ISO-8859-1>')
fpw.write(enc_iso8859_1_iso8859_1)
fpw.write('\n')

fpw.flush()
fpw.close()

控制台中的输出:

Origin> Катерина Александровна
(bytearray(b'\xd0\x9a\xd0\xb0\xd1\x82\xd0\xb5\xd1\x80\xd0\xb8\xd0\xbd\xd0\xb0 \xd0\x90\xd0\xbb\xd0\xb5\xd0\xba\xd1\x81\xd0\xb0\xd0\xbd\xd0\xb4\xd1\x80\xd0\xbe\xd0\xb2\xd0\xbd\xd0\xb0'),)

ISO-8859-1 decoding> ÐаÑеÑина ÐлекÑандÑовна 43
(u'\xd0\x9a\xd0\xb0\xd1\x82\xd0\xb5\xd1\x80\xd0\xb8\xd0\xbd\xd0\xb0 \xd0\x90\xd0\xbb\xd0\xb5\xd0\xba\xd1\x81\xd0\xb0\xd0\xbd\xd0\xb4\xd1\x80\xd0\xbe\xd0\xb2\xd0\xbd\xd0\xb0', 43)
UTF-8 encoding ISO-8859-1> ÐаÑеÑина ÐлекÑандÑовна
ISO-8859-1 encoding ISO-8859-1> Катерина Александровна

UTF-8 decoding> Катерина Александровна 43
(u'\u041a\u0430\u0442\u0435\u0440\u0438\u043d\u0430 \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440\u043e\u0432\u043d\u0430', 43)
UTF-8 encoding UTF-8> Катерина Александровна

UTF-8 encoding ISO-8859-1> ÐаÑеÑина ÐлекÑандÑовна 43
('\xc3\x90\xc2\x9a\xc3\x90\xc2\xb0\xc3\x91\xc2\x82\xc3\x90\xc2\xb5\xc3\x91\xc2\x80\xc3\x90\xc2\xb8\xc3\x90\xc2\xbd\xc3\x90\xc2\xb0 \xc3\x90\xc2\x90\xc3\x90\xc2\xbb\xc3\x90\xc2\xb5\xc3\x90\xc2\xba\xc3\x91\xc2\x81\xc3\x90\xc2\xb0\xc3\x90\xc2\xbd\xc3\x90\xc2\xb4\xc3\x91\xc2\x80\xc3\x90\xc2\xbe\xc3\x90\xc2\xb2\xc3\x90\xc2\xbd\xc3\x90\xc2\xb0', 43)

ISO-8859-1 encoding ISO-8859-1> Катерина Александровна 43
('\xd0\x9a\xd0\xb0\xd1\x82\xd0\xb5\xd1\x80\xd0\xb8\xd0\xbd\xd0\xb0 \xd0\x90\xd0\xbb\xd0\xb5\xd0\xba\xd1\x81\xd0\xb0\xd0\xbd\xd0\xb4\xd1\x80\xd0\xbe\xd0\xb2\xd0\xbd\xd0\xb0', 43)

文件中的输出名为output.txt

Origin>Катерина Александровна
UTF-8 encoding ISO-8859-1: dec_iso8859_1.encode("utf-8")>ÐаÑеÑина ÐлекÑандÑовна
UTF-8 encoding UTF-8: dec_utf8.encode("utf-8")>Катерина Александровна
UTF-8 encoding ISO-8859-1>ÐаÑеÑина ÐлекÑандÑовна
ISO-8859-1 encoding ISO-8859-1>Катерина Александровна