The field by field update was completely crappy, now it's better.

This commit is contained in:
Bertrand Chenal committed 2008-01-11 00:11:26 +01:00
1 parent df9131dfc4
commit 6f0e39241c
1 file changed
+51 -33
+51 -33
View File
@@ -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