Migration done

This commit is contained in:
Jonas Linter
2025-11-19 15:01:16 +01:00
parent 6c46c566ed
commit d88a53327f
4 changed files with 87 additions and 4 deletions

View File

@@ -0,0 +1,65 @@
"""add hashed_customer_id to reservations with cascade delete
Revision ID: 08fe946414d8
Revises: 70b2579d1d96
Create Date: 2025-11-19 14:57:27.178924
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = '08fe946414d8'
down_revision: Union[str, Sequence[str], None] = '70b2579d1d96'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column('hashed_customers', 'customer_id',
existing_type=sa.INTEGER(),
nullable=True)
op.drop_constraint(op.f('hashed_customers_customer_id_fkey'), 'hashed_customers', type_='foreignkey')
op.create_foreign_key(None, 'hashed_customers', 'customers', ['customer_id'], ['id'], ondelete='SET NULL')
op.drop_constraint(op.f('reservations_customer_id_fkey'), 'reservations', type_='foreignkey')
op.create_foreign_key(None, 'reservations', 'customers', ['customer_id'], ['id'], ondelete='SET NULL')
# Add hashed_customer_id column to reservations with cascade delete
op.add_column('reservations', sa.Column('hashed_customer_id', sa.Integer(), nullable=True))
op.create_index(op.f('ix_reservations_hashed_customer_id'), 'reservations', ['hashed_customer_id'], unique=False)
op.create_foreign_key(None, 'reservations', 'hashed_customers', ['hashed_customer_id'], ['id'], ondelete='CASCADE')
# ### end Alembic commands ###
# Data migration: Populate hashed_customer_id from customer relationship
connection = op.get_bind()
update_stmt = sa.text("""
UPDATE reservations r
SET hashed_customer_id = hc.id
FROM hashed_customers hc
WHERE r.customer_id = hc.customer_id
AND hc.customer_id IS NOT NULL
""")
connection.execute(update_stmt)
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
# Drop the hashed_customer_id column and its constraints
op.drop_constraint(None, 'reservations', type_='foreignkey')
op.drop_index(op.f('ix_reservations_hashed_customer_id'), table_name='reservations')
op.drop_column('reservations', 'hashed_customer_id')
op.drop_constraint(None, 'reservations', type_='foreignkey')
op.create_foreign_key(op.f('reservations_customer_id_fkey'), 'reservations', 'customers', ['customer_id'], ['id'])
op.drop_constraint(None, 'hashed_customers', type_='foreignkey')
op.create_foreign_key(op.f('hashed_customers_customer_id_fkey'), 'hashed_customers', 'customers', ['customer_id'], ['id'])
op.alter_column('hashed_customers', 'customer_id',
existing_type=sa.INTEGER(),
nullable=False)
# ### end Alembic commands ###

View File

@@ -253,7 +253,8 @@ class ConversionService:
# Load all reservations with their hashed customers in one query
from sqlalchemy.orm import selectinload
query = select(Reservation).options(
selectinload(Reservation.customer).selectinload(Customer.hashed_version)
selectinload(Reservation.customer).selectinload(Customer.hashed_version),
selectinload(Reservation.hashed_customer)
)
result = await session.execute(query)
reservations = result.scalars().all()
@@ -265,9 +266,11 @@ class ConversionService:
hotel_code = reservation.hotel_code
if hotel_code not in self._reservation_cache:
self._reservation_cache[hotel_code] = []
# Cache the hashed customer instead of raw customer
# Cache the hashed customer - prefer direct relationship, fall back to customer relationship
hashed_customer = None
if reservation.customer and reservation.customer.hashed_version:
if reservation.hashed_customer:
hashed_customer = reservation.hashed_customer
elif reservation.customer and reservation.customer.hashed_version:
hashed_customer = reservation.customer.hashed_version
self._reservation_cache[hotel_code].append(
(reservation, hashed_customer)

View File

@@ -478,6 +478,7 @@ class Reservation(Base):
__tablename__ = "reservations"
id = Column(Integer, primary_key=True)
customer_id = Column(Integer, ForeignKey("customers.id", ondelete="SET NULL"))
hashed_customer_id = Column(Integer, ForeignKey("hashed_customers.id", ondelete="CASCADE"))
unique_id = Column(String, unique=True)
md5_unique_id = Column(String(32), unique=True) # max length 32 guaranteed
start_date = Column(Date)
@@ -507,6 +508,7 @@ class Reservation(Base):
room_classification_code = Column(String)
room_type = Column(String)
customer = relationship("Customer", back_populates="reservations")
hashed_customer = relationship("HashedCustomer", backref="reservations")
# Table for tracking acknowledged requests by client

View File

@@ -7,7 +7,7 @@ from typing import Optional
from sqlalchemy import and_, select
from sqlalchemy.ext.asyncio import AsyncSession
from .db import AckedRequest, Customer, Reservation
from .db import AckedRequest, Customer, HashedCustomer, Reservation
from .schemas import ReservationData
@@ -63,6 +63,19 @@ class ReservationService:
reservation = self._convert_reservation_data_to_db(
reservation_data, customer_id
)
# Automatically populate hashed_customer_id from the customer
# Since hashed_customer is always created when a customer is created,
# we can get it by querying for the hashed_customer with matching customer_id
hashed_customer_result = await self.session.execute(
select(HashedCustomer).where(
HashedCustomer.customer_id == customer_id
)
)
hashed_customer = hashed_customer_result.scalar_one_or_none()
if hashed_customer:
reservation.hashed_customer_id = hashed_customer.id
self.session.add(reservation)
if auto_commit: