Odoo自定义模块中Python处理CSV文件的编码报错排查
Odoo CSV导入解码错误排查与修复
错误根源
ir.attachment.datas字段格式错误:该字段要求存储base64编码的字符串,你直接传入未编码的文件内容字符串,Odoo会尝试将其当作base64解码,导致格式不匹配报错。- 文件读取类型不匹配:用
'r'模式读取文件得到的是字符串,而base64.b64encode仅接受字节对象,因此触发类型错误。 - 附件对象无法直接解析:
import_csv方法接收的是ir.attachment记录,但csv.reader需要类文件对象或可迭代行数据,直接传附件对象不符合解析要求。
修正后的完整代码
import base64 import csv from io import StringIO def import_csv(self, attachment): # 解码附件存储的base64数据,转成UTF-8字符串 csv_content = base64.b64decode(attachment.datas).decode('utf-8') # 用StringIO包装字符串为类文件对象,供csv.reader读取 reader = csv.reader(StringIO(csv_content)) next(reader) # 跳过表头行 for row in reader: record = { 'name': row[0], 'component_name': row[1], 'percentage': row[2], 'processing_start_date': row[3], 'finished_real_date': row[4], } self.env['item.master'].create(record) def action_import_csv(self): # 以二进制模式读取文件,直接获取字节对象 with open('test.csv', 'rb') as outfile: data_bytes = outfile.read() # 编码为base64字节后转成字符串,符合ir.attachment.datas的存储要求 data_record = base64.b64encode(data_bytes).decode('utf-8') ir_values = { 'name': 'test.csv', 'datas': data_record, } data_id = self.env['ir.attachment'].sudo().create(ir_values) self.import_csv(data_id)
核心修改说明
- 文件读取模式:改用
'rb'二进制模式读取,直接获取字节数据,避免字符串与字节的类型冲突。 - Base64编码流程:读取字节后编码为base64,再转成字符串存入
datas字段,完全匹配Odoo的存储要求。 - 附件内容解析:从附件的
datas解码出原始内容,用StringIO包装成类文件对象,让csv.reader可以正常解析行数据。 - 资源管理:使用
with语句自动关闭文件句柄,避免资源泄漏。
内容的提问来源于stack exchange,提问作者Andromeda
相关产品推荐
相关产品推荐

