odoo18/addons/point_of_sale/upgrades/1.0.2/post-deduplicate-uuids.py

41 lines
1.4 KiB
Python

import uuid
from psycopg2.extras import Json
def migrate(cr, version):
"""
When UUIDs were introduced for POS [order, order.line, payment] records,
they were initially generated on the backend, defined as the default value
on the column. The issue with this is that during the upgrade to 18.0+
from a version < 18.0, this default value is determined once for the column
and then applied to all records, resulting in one UUID, duplicated across
all existing POS records.
This migration fixes the issue by generating a new UUID for each record
that has the same UUID as another record. Specifically, it does this for
the following tables:
- pos_order
- pos_order_line
- pos_payment
"""
def deduplicate_uuids(table):
query = f"""
SELECT UNNEST(ARRAY_AGG(id))
FROM {table}
WHERE uuid IS NOT NULL
GROUP BY uuid
HAVING COUNT(*) > 1
"""
while True:
cr.execute(query)
if not cr.rowcount:
break
ids = tuple(r[0] for r in cr.fetchmany(10000))
cr.execute(
f"UPDATE {table} SET uuid = (%s::json)->>(id::text) WHERE id IN %s",
[Json({id_: str(uuid.uuid4()) for id_ in ids}), ids]
)
deduplicate_uuids("pos_order")
deduplicate_uuids("pos_order_line")
deduplicate_uuids("pos_payment")