41 lines
1.4 KiB
Python
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")
|