【发布时间】:2017-05-06 10:37:12
【问题描述】:
Odoo 9 自定义模块二进制字段 attachment=True 参数稍后添加,新记录将存储在文件系统存储中。 二进制字段一些旧记录附件 = True 未使用,因此未在 ir.attachment 表中创建旧记录条目并且未保存文件系统。 我想知道如何迁移文件系统存储中的旧记录二进制字段值存储?如何根据旧记录二进制字段值在 ir_attachment 行中创建/插入记录?有没有可用的脚本?
【问题讨论】:
Odoo 9 自定义模块二进制字段 attachment=True 参数稍后添加,新记录将存储在文件系统存储中。 二进制字段一些旧记录附件 = True 未使用,因此未在 ir.attachment 表中创建旧记录条目并且未保存文件系统。 我想知道如何迁移文件系统存储中的旧记录二进制字段值存储?如何根据旧记录二进制字段值在 ir_attachment 行中创建/插入记录?有没有可用的脚本?
【问题讨论】:
您必须在配置文件中包含pg_path 中的postgre bin 路径。这将恢复包含二进制字段的文件存储
pg_path = D:\fx\upsynth_Postgres\bin
【讨论】:
我确信您不再需要 18 个月前提出的解决方案,但我刚刚遇到了同样的问题(数据库中有许多 GB 的二进制数据),这个问题出现在 Google 上,所以我我想我会分享我的解决方案。
当您设置 attachment=True 时,二进制列将保留在数据库中,但系统将在文件存储中查找数据。这使我无法从 Odoo API 访问数据,因此我需要直接从数据库中检索二进制数据,然后使用 Odoo 将二进制数据重新写入记录,最后删除列并清理表。
这是我的脚本,它的灵感来自 this solution 用于迁移附件,但此解决方案适用于任何模型中的任何字段,并从数据库而不是从 Odoo API 读取二进制数据。
import xmlrpclib
import psycopg2
username = 'your_odoo_username'
pwd = 'your_odoo_password'
url = 'http://ip-address:8069'
dbname = 'database-name'
model = 'model.name'
field = 'field_name'
dbuser = 'postgres_user'
dbpwd = 'postgres_password'
dbhost = 'postgres_host'
conn = psycopg2.connect(database=dbname, user=dbuser, password=dbpwd, host=dbhost, port='5432')
cr = conn.cursor()
# Get the uid
sock_common = xmlrpclib.ServerProxy ('%s/xmlrpc/common' % url)
uid = sock_common.login(dbname, username, pwd)
sock = xmlrpclib.ServerProxy('%s/xmlrpc/object' % url)
def migrate_attachment(res_id):
# 1. get data
cr.execute("SELECT %s from %s where id=%s" % (field, model.replace('.', '_'), res_id))
data = cr.fetchall()[0][0]
# Re-Write attachment
if data:
data = str(data)
sock.execute(dbname, uid, pwd, model, 'write', [res_id], {field: str(data)})
return True
else:
return False
# SELECT attachments:
records = sock.execute(dbname, uid, pwd, model, 'search', [])
cnt = len(records)
print cnt
i = 0
for res_id in records:
att = sock.execute(dbname, uid, pwd, model, 'read', res_id, [field])
status = migrate_attachment(res_id)
print 'Migrated ID %s (attachment %s of %s) [Contained data: %s]' % (res_id, i, cnt, status)
i += 1
cr.close()
print "done ..."
然后,删除列并在 psql 中清理表。
【讨论】: