Как я могу перенести старое двоичное поле Odoo в новые версии odoo с вложением = True?

#postgresql #odoo #odoo-8 #odoo-10 #odoo-9

#postgresql #odoo #odoo-8 #odoo-10 #odoo-9

Вопрос:

У меня старая версия odoo (v6), и я переношу ее на odoo-10, проблема, с которой я сталкиваюсь, связана с переносом данных двоичного поля. Поскольку odoo-10 имеет атрибут «attachment = True», но для более старых версий этого не было. Итак, могу ли я получить небольшое представление от сообщества stack о том, как я могу выполнить свою задачу и как я могу перенести эту таблицу postgres в данные, совместимые с odoo-10. Заранее спасибо.

Ответ №1:

Просто перенесите данные как есть, пусть они существуют в базе данных. Мне пришлось написать модуль для достижения того же требования, потому что у клиента были вложения в базе данных вместо использования вложений.

Следующий код работает, его нет официально в приложениях моей компании в App Store 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})
  

Вы должны написать a ir.cron или a ir.actions.server , чтобы использовать этот метод.

Ответ №2:

Если вы посмотрите на функцию чтения для двоичного класса ( <path_to_v12>/odoo/fields.py lines 1786-1800 , приведенную ниже), вы заметите, что она ir.attachment ищет записи, имеющие правильную модель, поле и идентификатор.

 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 поле ссылающейся записи).

Комментарии:

1. Он поступает из OpenERP 6 без ir.attachment записей. В те средневековые времена двоичные данные сохранялись как bytea непосредственно в базе данных. Извините, но это неправильный ответ, но хороший намек на то, как Odoo считывает двоичные поля attachment=True .

2. Извините за это, я едва коснулся версии 6. @CZoellner спасибо за совет! Учитывая, что этот ответ неверен, должен ли я его удалить?

3. Нет, пусть это останется.

Ответ №3:

Лучше всего использовать XMLRPC для чтения данных из SRC и записи данных в DEST. Что решит вашу проблему. Он будет считывать данные из двоичного поля при создании вложения, которое оно сохранит в файловой системе.