Python3.4下如何将StringIO对象传入Vertica COPY命令?
解决Vertica copy命令兼容StringIO的问题
嘿,我之前也碰到过一模一样的问题!Vertica的cursorV.copy()方法底层其实是期望字节流输入的,而StringIO存储的是字符串类型的数据,这就是为什么会抛出Can't concat bytes to str的错误——方法内部在处理时试图把字符串和字节拼接,类型不匹配导致的。
下面给你两种可行的解决办法:
方法一:将StringIO内容转换为BytesIO
这是最直接的思路,先把StringIO里的字符串内容编码成字节,再存入BytesIO对象,这样就能满足Vertica的要求了:
from io import StringIO, BytesIO import csv from openpyxl import load_workbook # 第一步:用StringIO生成CSV内容(你的原有逻辑) wb = load_workbook('your_excel_file.xlsx') ws = wb.active string_output = StringIO() csv_writer = csv.writer(string_output) for row in ws.iter_rows(values_only=True): csv_writer.writerow(row) string_output.seek(0) # 重置流的指针到开头 # 第二步:转换为BytesIO csv_content = string_output.getvalue().encode('utf-8') # 编码格式根据你的数据调整,比如gbk byte_output = BytesIO(csv_content) byte_output.seek(0) # 第三步:传入Vertica的copy命令 copy_query = "COPY your_target_table FROM STDIN DELIMITER ',' CSV" cursorV.copy(copy_query, byte_output)
方法二:直接使用BytesIO生成CSV
如果不想多一步转换,也可以直接用BytesIO来生成CSV内容,通过codecs.TextIOWrapper把字节流包装成文本流,这样csv.writer就能直接写入字符串了:
from io import BytesIO import csv from openpyxl import load_workbook import codecs wb = load_workbook('your_excel_file.xlsx') ws = wb.active byte_output = BytesIO() # 用TextIOWrapper包装BytesIO,指定编码 text_stream = codecs.getwriter('utf-8')(byte_output) csv_writer = csv.writer(text_stream) for row in ws.iter_rows(values_only=True): csv_writer.writerow(row) byte_output.seek(0) # 重置指针 # 执行copy操作 copy_query = "COPY your_target_table FROM STDIN DELIMITER ',' CSV" cursorV.copy(copy_query, byte_output)
注意事项
- 确保编码一致:CSV内容的编码要和Vertica数据库的字符集匹配,不然可能会出现乱码问题,常见的编码是
utf-8或者gbk,根据你的数据情况选择。 - Python3.4版本兼容性:确认你使用的
openpyxl版本支持Python3.4,避免版本不兼容的问题。
内容的提问来源于stack exchange,提问作者Tahreem Iqbal
相关产品推荐
相关产品推荐

