Skip to content

Commit 86e621f

Browse files
committed
[IMP] _change_foreign_key_refs: Add extra_where params
Adding the new argument `extra_where`, we are able to change a FK reference depending on an extra condition, so not all ocurrences are replaced. This is useful for example when we have a unique record for all companies, and on new version, there should be one record per company. We perform the split, and we need to replace references for only a specific company (extra_where="AND company_id = X"). Retro-compatibility is kept as the argument is optional, and a safeguard has been introduced for skipping models where the condition can't be fulfilled if the field doesn't exist (so we are not able to say if the reference should be replaced or not). TT28115
1 parent 5b374a2 commit 86e621f

File tree

1 file changed

+16
-9
lines changed

1 file changed

+16
-9
lines changed

openupgradelib/openupgrade_merge_records.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import functools
88
from psycopg2 import sql
99
from psycopg2 import ProgrammingError, IntegrityError
10-
from psycopg2.errorcodes import UNIQUE_VIOLATION
10+
from psycopg2.errorcodes import UNDEFINED_COLUMN, UNIQUE_VIOLATION
1111
from psycopg2.extensions import AsIs
1212
from .openupgrade import logged_query, version_info
1313
from .openupgrade_tools import column_exists, table_exists
@@ -17,7 +17,7 @@
1717

1818

1919
def _change_foreign_key_refs(env, model_name, record_ids, target_record_id,
20-
exclude_columns, model_table):
20+
exclude_columns, model_table, extra_where=None):
2121
# As found on https://stackoverflow.com/questions/1152260
2222
# /postgres-sql-to-list-table-foreign-keys
2323
# Adapted for specific Odoo structures like many2many tables
@@ -39,20 +39,27 @@ def _change_foreign_key_refs(env, model_name, record_ids, target_record_id,
3939
# Try one big swoop first
4040
env.cr.execute('SAVEPOINT sp1') # can't use env.cr.savepoint() in base
4141
try:
42+
query = sql.SQL(
43+
"""UPDATE {table}
44+
SET {column} = %(target_record_id)s
45+
WHERE {column} in %(record_ids)s"""
46+
).format(
47+
table=sql.Identifier(table), column=sql.Identifier(column),
48+
)
49+
if extra_where:
50+
query += sql.SQL(extra_where)
4251
logged_query(
43-
env.cr, """UPDATE %(table)s
44-
SET "%(column)s" = %(target_record_id)s
45-
WHERE "%(column)s" in %(record_ids)s
46-
""", {
47-
'table': AsIs(table),
48-
'column': AsIs(column),
52+
env.cr, query, {
4953
'record_ids': record_ids,
5054
'target_record_id': target_record_id,
5155
}, skip_no_result=True,
5256
)
5357
except (ProgrammingError, IntegrityError) as error:
5458
env.cr.execute('ROLLBACK TO SAVEPOINT sp1')
55-
if error.pgcode != UNIQUE_VIOLATION:
59+
if error.pgcode == UNDEFINED_COLUMN and extra_where:
60+
# extra_where is introducing a bad column. Ignore this table.
61+
continue
62+
elif error.pgcode != UNIQUE_VIOLATION:
5663
raise
5764
# Fallback on setting each row separately
5865
m2m_table = not column_exists(env.cr, table, 'id')

0 commit comments

Comments
 (0)