The field by field update was completely crappy, now it's better.
This commit is contained in:
1 parent
df9131dfc4
commit
6f0e39241c
1 file changed
+51
-33
+51
-33
@@ -1,6 +1,6 @@
|
||||
"model"
|
||||
from trytond.osv import fields, OSV
|
||||
from trytond.netsvc import Logger, LocalService, LOG_ERROR, LOG_INFO, LOG_WARNING
|
||||
from trytond.netsvc import Logger, LocalService, LOG_ERROR, LOG_INFO, LOG_WARNING, LOG_DEBUG
|
||||
from trytond.osv.orm import except_orm
|
||||
from trytond.tools import Cache
|
||||
import time
|
||||
@@ -172,7 +172,7 @@ class ModelData(OSV):
|
||||
module_data_ids = self.search(cursor, user,[])
|
||||
self.fs2db[cursor.dbname] = dict([
|
||||
((x.fs_id, x.module),
|
||||
(x.db_id, x.model)) for x in \
|
||||
(x.db_id, x.model, x.id)) for x in \
|
||||
self.browse(cursor, user, module_data_ids)])
|
||||
|
||||
def populate_fs2values(self, cursor, user):
|
||||
@@ -221,23 +221,27 @@ class ModelData(OSV):
|
||||
|
||||
if (fs_id, module) in self.fs2db[cursor.dbname]:
|
||||
# this record is already in the db:
|
||||
db_id, db_model = \
|
||||
db_id, db_model, mdata_id = \
|
||||
self.fs2db[cursor.dbname][(fs_id, module)]
|
||||
old_values = self.fs2values[cursor.dbname][(fs_id, module)]
|
||||
old_values = eval(old_values)
|
||||
|
||||
# Check if this record has been modified in the db:
|
||||
|
||||
# Check if values for this record has been modified in the
|
||||
# db, if not it's ok to overwrite them.
|
||||
if model != db_model:
|
||||
raise Exception("This record try to overwrite"
|
||||
"data with the wrong model.")
|
||||
object_ref = self.pool.get(model)
|
||||
db_values = object_ref.read(cursor, user, db_id, old_values.keys())
|
||||
# XXX maybe use a browse instead:
|
||||
db_values = object_ref.read(cursor, user, db_id, values.keys())
|
||||
|
||||
modified = False
|
||||
for key in old_values:
|
||||
to_update = {}
|
||||
for key in values:
|
||||
|
||||
# first handle correctly the datas returned by read()
|
||||
if object_ref._columns[key]._type == 'many2one':
|
||||
db_field = db_values[key][0]
|
||||
db_field = db_values[key] and db_values[key][0] or False
|
||||
elif object_ref._columns[key]._type in ['one2one', 'one2many', "many2many"]:
|
||||
logger = Logger()
|
||||
logger.notify_channel('init', LOG_WARNING,
|
||||
@@ -246,15 +250,38 @@ class ModelData(OSV):
|
||||
else:
|
||||
db_field = db_values[key]
|
||||
|
||||
if old_values[key] != db_field:
|
||||
modified = True
|
||||
break
|
||||
# if the fs value is the same has in the db, whe ignore it
|
||||
if db_field == values[key]:
|
||||
continue
|
||||
|
||||
if not modified:
|
||||
# Update the model_data with the modified values
|
||||
# we cannot update a field if it was changed by a user
|
||||
if key not in old_values:
|
||||
default_value = object_ref._defaults.get(
|
||||
key, lambda *a:None)(cursor, user)
|
||||
if db_field != default_value:
|
||||
logger = Logger()
|
||||
logger.notify_channel('init', LOG_WARNING,
|
||||
"Field %s of %s@%s not updated (id: %s), because "\
|
||||
"it has changed since the last update"% \
|
||||
(key, db_id, model, fs_id))
|
||||
continue
|
||||
|
||||
self.pool.get(model).write(cursor, user, db_id, values)
|
||||
self.create(cursor, user, {
|
||||
elif (old_values[key] and db_field) and old_values[key] != db_field:
|
||||
logger = Logger()
|
||||
logger.notify_channel('init', LOG_WARNING,
|
||||
"Field %s of %s@%s not updated (id: %s), because "\
|
||||
"it has changed since the last update."% (key, db_id, model, fs_id))
|
||||
continue
|
||||
|
||||
# so, the field in the fs and in the db are different,
|
||||
# and no user changed the value in the db:
|
||||
to_update[key] = values[key]
|
||||
|
||||
# if there is values to update:
|
||||
if to_update:
|
||||
self.pool.get(model).write(cursor, user, db_id, to_update)
|
||||
if values != old_values:
|
||||
self.write(cursor, user, mdata_id, {
|
||||
'fs_id': fs_id,
|
||||
'model': model,
|
||||
'module': module,
|
||||
@@ -263,19 +290,13 @@ class ModelData(OSV):
|
||||
'date_update': time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
})
|
||||
|
||||
else:
|
||||
# We may not overwrite modified data:
|
||||
logger = Logger()
|
||||
logger.notify_channel('init', LOG_INFO,
|
||||
'Record %s ignored, the corresponding data (%s@%s) '
|
||||
'in the db has been modified' % (fs_id,db_id, model))
|
||||
# Remove this record from the value list. This means that
|
||||
# the corresponding record have been found.
|
||||
del self.fs2values[cursor.dbname][(fs_id, module)]
|
||||
else:
|
||||
# this record is new
|
||||
db_id = self.pool.get(model).create(cursor, user, values)
|
||||
self.create(cursor, user, {
|
||||
mdata_id = self.create(cursor, user, {
|
||||
'fs_id': fs_id,
|
||||
'model': model,
|
||||
'module': module,
|
||||
@@ -283,11 +304,11 @@ class ModelData(OSV):
|
||||
'values': str(values),
|
||||
})
|
||||
# update fs2db:
|
||||
self.fs2db[cursor.dbname][(fs_id, module)]= (db_id, model, str(values))
|
||||
self.fs2db[cursor.dbname][(fs_id, module)]= (db_id, model, str(values), mdata_id)
|
||||
|
||||
def post_import(self, cursor, user, modules):
|
||||
|
||||
# Test because of a wrong extra call see todo at the end of
|
||||
# Test because of a wrong extra call. See todo at the end of
|
||||
# load_module_graph in module.py
|
||||
# Globaly this function is a bit dirty.
|
||||
if not (self.fs2values and self.fs2values.get(cursor.dbname)):
|
||||
@@ -295,11 +316,11 @@ class ModelData(OSV):
|
||||
|
||||
wf_service = LocalService("workflow")
|
||||
|
||||
data_unlink = []
|
||||
mdata_unlink = []
|
||||
|
||||
for (fs_id, module) in self.fs2values[cursor.dbname]:
|
||||
if module in modules:
|
||||
(db_id, model, values) = self.fs2db[cursor.dbname][(fs_id, module)]
|
||||
(db_id, model, mdata_id) = self.fs2db[cursor.dbname][(fs_id, module)]
|
||||
|
||||
if model == 'workflow.activity':
|
||||
cursor.execute('SELECT res_type, db_id ' \
|
||||
@@ -323,8 +344,9 @@ class ModelData(OSV):
|
||||
'Deleting %s@%s' % (db_id, model))
|
||||
try:
|
||||
self.pool.get(model).unlink(cursor, user, db_id)
|
||||
data_unlink.append((fs_id, module))
|
||||
mdata_unlink.append(mdata_id)
|
||||
except:
|
||||
raise
|
||||
logger.notify_channel('init', LOG_ERROR,
|
||||
'Could not delete id: %d of model %s\t' \
|
||||
'There should be some relation ' \
|
||||
@@ -333,12 +355,8 @@ class ModelData(OSV):
|
||||
'and restart --update=module' % \
|
||||
(db_id, model))
|
||||
|
||||
if data_unlink:
|
||||
cursor.execute("""
|
||||
DELETE FROM ir_model_data
|
||||
WHERE (fs_id, module) in (%s)
|
||||
"""% ','.join(["('%s','%s')"%x for x in data_unlink]))
|
||||
|
||||
if mdata_unlink:
|
||||
self.unlink(cursor, user, mdata_unlink)
|
||||
del self.fs2values[cursor.dbname]
|
||||
|
||||
return True
|
||||
|
||||
Reference in new issue
Block a user