【问题标题】:How can I migrate Odoo old binary field to new odoo versions with attachment=True?如何将 Odoo 旧二进制字段迁移到附件 = True 的新 odoo 版本?
【发布时间】:2019-04-12 09:43:39
【问题描述】:

我有一个旧的 odoo 版本 (v6),我正在将其迁移到 odoo-10,我面临的问题是二进制字段数据迁移。由于 odoo-10 具有属性“attachment=True”,但对于旧版本,这不存在。 因此,我能否从堆栈社区获得一点想法,关于如何完成我的任务以及如何将 postgres 表迁移到 odoo-10 兼容数据。提前致谢。

【问题讨论】:

    标签: postgresql odoo odoo-8 odoo-10 odoo-9


    【解决方案1】:

    只需原样迁移数据,让它们存在于数据库中。我必须编写一个模块来实现相同的要求,因为客户在数据库中有附件而不是使用附件。

    以下代码有效,它不在我公司在 Odoo 应用商店的应用程序中,但最终会找到它的方式 ;-)

    from odoo import api, models, exceptions
    from odoo.osv import expression
    
    
    class IrAttachment(models.Model):
        """ Attachment Extensions"""
    
        _inherit = 'ir.attachment'
    
        @api.model
        def _relocate_binary_data(
                self, model=None, fields=None, domain=None, limit=0):
            """ Relocates binary data into attachments. This method
                has no functionality to reverse the process.
    
                Use this to change binary fields to attachment usage,
                which is done by using the parameter attachment=True
    
                @param model: Model Name (required)
                @param fields: List of binary field names (required)
                @param domain: optional search domain to filter treated records
                    (default: []==no filter)
                @param limit: optional filter limit (default: 0==unlimited)"""
            if not model or not fields:
                raise exceptions.Warning(
                    "model and fields are required parameters")
            # only touch records with binary data in one of the provided fields
            default_domain = [[(f, '!=', False)] for f in fields]
            default_domain = expression.OR(default_domain)
            domain = expression.AND([domain, default_domain])
            records = self.env[model].with_context(active_test=False).search(
                domain, limit=limit)
            # relocate the binary data to attachments
            for record in records:
                for field in fields:
                    # search for existing attachments (for re-runs)
                    attachment = records.env['ir.attachment'].sudo().search([
                        ('res_model', '=', record._name),
                        ('res_field', '=', field),
                        ('res_id', '=', record.id),
                    ])
                    # write the binary value to existing attachment or create one
                    if attachment:
                        attachment.write({'datas': getattr(record, field)})
                    else:
                        self.env['ir.attachment'].create({
                            'name': record.name,
                            'res_model': record._name,
                            'res_field': field,
                            'res_id': record.id,
                            'type': 'binary',
                            'datas': getattr(record, field)
                        })
            # empty the database binary data
            records.write({f: None for f in fields})
    

    您必须编写ir.cronir.actions.server 才能使用此方法。

    【讨论】:

      【解决方案2】:

      如果您查看 Binary 类(<path_to_v12>/odoo/fields.py lines 1786-1800,下文引用)的读取函数,您会注意到它会搜索 ir.attachment 以查找具有正确模型、字段和 ID 的记录。

      def read(self, records):
          # values are stored in attachments, retrieve them
          assert self.attachment
          domain = [
              ('res_model', '=', records._name),
              ('res_field', '=', self.name),
              ('res_id', 'in', records.ids),
          ]
          # Note: the 'bin_size' flag is handled by the field 'datas' itself
          data = {att.res_id: att.datas
                  for att in records.env['ir.attachment'].sudo().search(domain)}
          cache = records.env.cache
          for record in records:
              cache.set(record, self, data.get(record.id, False))
      

      所以,我有根据的猜测是您可以更新您的“ir_attachment”记录并添加res_model(注意这是一个字符串!)、res_field(也是一个字符串)和res_id(这是一个整数保存在引用记录的id 字段中)。

      【讨论】:

      • 他来自 OpenERP 6,没有 ir.attachment 记录。在那个中世纪的日子里,二进制数据直接作为 bytea 保存在数据库中。很抱歉,但这不是正确的答案,而是一个很好的提示 Odoo 如何使用 attachment=True 读取二进制字段。
      • 很抱歉,我几乎没有接触过 v6。 @CZoellner 感谢您的建议!鉴于这个答案不正确,我应该删除它吗?
      • 不让它留下来。
      【解决方案3】:

      最好是使用 XMLRPC 从 SRC 读取数据并将数据写入 DEST。哪个会解决您的问题。它会在创建附件时从二进制字段中读取数据,并将其存储在文件系统中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-12-09
        • 2021-02-21
        • 2016-04-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多