clearcorp team mailing list archive
-
clearcorp team
-
Mailing list archive
-
Message #00611
lp:~wg.clearcorp/openerp-ccorp-addons/6.1-instance-generic-merge into lp:openerp-ccorp-addons
Willy Andres Gomez Solorzano has proposed merging lp:~wg.clearcorp/openerp-ccorp-addons/6.1-instance-generic-merge into lp:openerp-ccorp-addons.
Requested reviews:
Ronald Rubi (rr.clearcorp)
For more details, see:
https://code.launchpad.net/~wg.clearcorp/openerp-ccorp-addons/6.1-instance-generic-merge/+merge/146144
Fixed error of unique constraint in rel tables
--
https://code.launchpad.net/~wg.clearcorp/openerp-ccorp-addons/6.1-instance-generic-merge/+merge/146144
Your team CLEARCORP development team is subscribed to branch lp:openerp-ccorp-addons.
=== added file 'generic_instance_merge/foreign_query.sql'
--- generic_instance_merge/foreign_query.sql 1970-01-01 00:00:00 +0000
+++ generic_instance_merge/foreign_query.sql 2013-02-01 15:02:27 +0000
@@ -0,0 +1,12 @@
+SELECT A.relname AS tabla, C.attname AS columna, B.relname AS tabla_foranea, D.attname AS columna_foranea
+ FROM pg_catalog.pg_constraint, pg_catalog.pg_class AS A, pg_catalog.pg_class AS B, pg_catalog.pg_attribute C, pg_catalog.pg_attribute D
+ WHERE contype = 'f'
+ AND conrelid = A.oid
+ AND confrelid = B.oid
+ AND conrelid = C.attrelid
+ AND confrelid = D.attrelid
+ AND C.attnum = pg_catalog.pg_constraint.conkey[1]
+ AND D.attnum = pg_catalog.pg_constraint.confkey[1]
+-- AND B.relname =''
+-- AND D.attname ='id'
+ ORDER BY tabla, columna, tabla_foranea, columna_foranea;
=== modified file 'generic_instance_merge/generic_instance_merge.py'
--- generic_instance_merge/generic_instance_merge.py 2013-01-21 20:54:37 +0000
+++ generic_instance_merge/generic_instance_merge.py 2013-02-01 15:02:27 +0000
@@ -26,12 +26,48 @@
import tools
from tools.translate import _
+
class generic_instance_merge(orm.Model):
_name = "generic.instance.merge"
_description = "Generic merging Library"
-
+ def get_values(self, msg, ref_field):
+ '''
+ Parses the error message "msg" to get the columns and values that produce integrity error.
+ Arguments:
+ "msg" - String, with the error message
+ "ref_field" - String, with the name of the referencing column
+ Returns:
+ key_values - List of dictionaries
+ '''
+ tmp = msg.split('=')
+ columns = tmp[0]
+ values = tmp[1]
+
+ tmp = columns.split('(')
+ columns = tmp[1]
+ comma_index=columns.find(',')
+ paren_index=columns.find(')')
+ field_1 = columns[0:comma_index]
+ field_2 = columns[comma_index + 2: paren_index]
+
+ comma_index=values.find(',')
+ paren_index=values.find(')')
+ value_1 = values[1:comma_index]
+ value_2 = values[comma_index +2: paren_index]
+
+ if ref_field == field_1: #if the referencing field is the field_1, field/value_1 goes first
+ key_values = [{'column' : field_1, 'value' : value_1 },{'column' : field_2, 'value' : value_2 }]
+ else:# field/value_1 goes second
+ key_values = [{'column' : field_2, 'value' : value_2 },{'column' : field_1, 'value' : value_1 }]
+ return key_values
+ def is_integrity_error(self, pgcode):
+ if pgcode == '23505':
+ return True
+ else:
+ return False
+
def merge(self, cr, uid,obj_class, id, ids, delete_merged=False, context=None):
'''
redirects all references from an "obj_class" instance with id in "ids" to the instance of "id"
@@ -56,19 +92,34 @@
'AND B.relname ='+"\'"+ obj_class +"\' " \
'AND D.attname ='+"\'id\' " \
'ORDER BY tabla, columna, tabla_foranea, columna_foranea;'
- cr.execute(dependencies_query)
+ cr.execute(dependencies_query) #gets foreign references to id
for line in cr.fetchall():
referencing_table = line[0]
referencing_field = line[1]
- for merging_id in ids:
- update_query="UPDATE "+ referencing_table + \
- " SET "+ referencing_field +" = "+ str(id) + \
- " WHERE "+ referencing_field +" = "+ str(merging_id)
- cr.execute(update_query)
+ for merging_id in ids: #for every reference, replaces the field id with value "id"
+ clean_exit = False #loop in case that an exception raises, until the respective ids are updated or deleted
+ while clean_exit == False:
+ try:
+ update_query= "UPDATE "+ referencing_table + \
+ " SET "+ referencing_field +" = "+ str(id) + \
+ " WHERE "+ referencing_field +" = "+ str(merging_id)
+ cr.execute(update_query)
+ clean_exit = True
+ cr.commit()
+ except Exception , e:
+ cr.rollback()
+ err=e[0]
+ if self.is_integrity_error(e.pgcode):
+ values = self.get_values(err, referencing_field) #in case of integrity error gets columns/values producing the conflict
+ delete_query = "DELETE FROM "+ referencing_table + \
+ " WHERE "+ values[0]['column'] +" = " + str(merging_id) + \
+ " AND "+ values[1]['column'] +" = " + values[1]['value']
+ cr.execute(delete_query)
+ print "***************************"
if delete_merged:
for deleting_id in ids:
if deleting_id != id:
- delete_query = "DELETE FROM "+ obj_class + \
- " WHERE id = "+ str(deleting_id)
+ delete_query = "DELETE FROM " + obj_class + \
+ " WHERE id = " + str(deleting_id)
cr.execute(delete_query)
return True
Follow ups