Probably this solution is too late for you. However this is my solution:
DON'T ADD attachment=True to the model field. Here is steps you should do:
1) Copy all the files somewhere in order to save them. You could use XML-RPC script. If you don't have any files and you've got empty database you could skip this step.
import xmlrpc.client as xmlrpclib
class API():
def __init__(self, srv, db, user, pwd):
common = xmlrpclib.ServerProxy(
'%s/xmlrpc/2/common' % srv)
self.api = xmlrpclib.ServerProxy(
'%s/xmlrpc/2/object' % srv)
self.uid = common.authenticate(db, user, pwd, {})
self.pwd = pwd
self.db = db
self.model = ''
def set_model(self, model):
self.model = model
def execute(self, method, arg_list, kwarg_dict=None):
return self.api.execute_kw(
self.db, self.uid, self.pwd, self.model,
method, arg_list, kwarg_dict or {})
def get(self, id=None, field='id'):
domain = [('id', '=', id), (field, '!=', False)] if id else []
return self.execute('search_read', [domain, [field]])
def get_fields(self, id=None, fields=[]):
domain = [('id', '=', id)] if id else []
return self.execute('search_read', [domain, fields])
def set(self, id=None, vals={}):
if vals:
self.execute('write', [[id], vals])
return id
from rpc_api import API
import os.path
if __name__ == '__main__':
srv, db = 'http://domainname.com', 'database_name'
user, pwd = 'admin', 'admin'
api = API(srv, db, user, pwd)
# Defining models
models = {
'model_name': [
'field1',
'field2'
]
}
for model, fields in models.items():
# Setting model
api.set_model(model)
# Fetching all
ids = [id.get('id') for id in api.get()]
for id in ids:
for field in fields:
filename = "attachments/%s-%s-%s" % (model, id, field)
# Check if file exists
if not os.path.exists(filename):
for val in api.get(id, field):
base64 = val.get(field)
if base64:
# Writing to file
with open(filename, 'w') as infile:
infile.write(base64)
print("%s CREATED" % filename)
else:
print("model: \"%s\" id: %s column: \"%s\" is EMPTY" % (model, id, field))
else:
print("%s ALREADY EXISTS" % filename)
2) Add attachment=True to your field in model.
fieldname = fields.Binary(string="Field 1", attachment=True)
3) Update/Upgrade your application and Restart server
odoo-bin --database=database_name --update=module_name
4) Delete field from the database. Execute following SQL script:
ALTER database DROP COLUMN fieldname;
P.S. if you don't delete column, it will save all files both in filestore and in database
5) Upload saved files (attachments) with following RPC script.
from rpc_api import API
import os
if __name__ == '__main__':
srv, db = 'http://domainname.com', 'database_name'
user, pwd = 'admin', 'admin'
api = API(srv, db, user, pwd)
path = 'attachments/'
for filename in os.listdir(path):
info = filename.split('-')
if len(info) != 3:
# Cannot be parsed
print("Filename: %s cannot be parsed" % filename)
continue
model, id, field = filename.split('-')
api.set_model(model)
base64 = open(path + filename).read()
# Setting value to record
api.set(int(id), {field: base64})
print("model: %s id: %s field: %s OK" % (model, id, field))
I don't know exactly is there any other proper ways to do that. This will work. Be careful with your database