285 lines
10 KiB
Python
285 lines
10 KiB
Python
"""Update conversions schema with new attribution fields and composite key for guests.
|
|
|
|
Revision ID: a2b3c4d5e6f7
|
|
Revises: 630b0c367dcb
|
|
Create Date: 2025-11-19 00:00:00.000000
|
|
|
|
"""
|
|
|
|
from collections.abc import Sequence
|
|
|
|
import sqlalchemy as sa
|
|
from alembic import op
|
|
|
|
# revision identifiers, used by Alembic.
|
|
revision: str = "a2b3c4d5e6f7"
|
|
down_revision: str | Sequence[str] | None = "630b0c367dcb"
|
|
branch_labels: str | Sequence[str] | None = None
|
|
depends_on: str | Sequence[str] | None = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
"""Upgrade schema."""
|
|
# Drop existing conversion tables to migrate to new schema
|
|
# Drop conversion_rooms first due to foreign key dependency
|
|
op.execute("DROP TABLE IF EXISTS conversion_rooms CASCADE")
|
|
op.execute("DROP TABLE IF EXISTS conversions CASCADE")
|
|
op.execute("DROP TABLE IF EXISTS conversion_guests CASCADE")
|
|
|
|
# Create conversion_guests table with composite primary key (hotel_id, guest_id)
|
|
op.create_table(
|
|
"conversion_guests",
|
|
sa.Column("hotel_id", sa.String(), nullable=False, primary_key=True),
|
|
sa.Column("guest_id", sa.String(), nullable=False, primary_key=True),
|
|
sa.Column("guest_first_name", sa.String(), nullable=True),
|
|
sa.Column("guest_last_name", sa.String(), nullable=True),
|
|
sa.Column("guest_email", sa.String(), nullable=True),
|
|
sa.Column("guest_country_code", sa.String(), nullable=True),
|
|
sa.Column("guest_birth_date", sa.Date(), nullable=True),
|
|
sa.Column("hashed_first_name", sa.String(64), nullable=True),
|
|
sa.Column("hashed_last_name", sa.String(64), nullable=True),
|
|
sa.Column("hashed_email", sa.String(64), nullable=True),
|
|
sa.Column("hashed_country_code", sa.String(64), nullable=True),
|
|
sa.Column("hashed_birth_date", sa.String(64), nullable=True),
|
|
sa.Column("is_regular", sa.Boolean(), default=False, nullable=False),
|
|
sa.Column("first_seen", sa.DateTime(timezone=True), nullable=True),
|
|
sa.Column("last_seen", sa.DateTime(timezone=True), nullable=True),
|
|
sa.PrimaryKeyConstraint("hotel_id", "guest_id"),
|
|
)
|
|
op.create_index(
|
|
op.f("ix_conversion_guests_hotel_id"),
|
|
"conversion_guests",
|
|
["hotel_id"],
|
|
unique=False,
|
|
)
|
|
op.create_index(
|
|
op.f("ix_conversion_guests_guest_id"),
|
|
"conversion_guests",
|
|
["guest_id"],
|
|
unique=False,
|
|
)
|
|
op.create_index(
|
|
op.f("ix_conversion_guests_hashed_first_name"),
|
|
"conversion_guests",
|
|
["hashed_first_name"],
|
|
unique=False,
|
|
)
|
|
op.create_index(
|
|
op.f("ix_conversion_guests_hashed_last_name"),
|
|
"conversion_guests",
|
|
["hashed_last_name"],
|
|
unique=False,
|
|
)
|
|
op.create_index(
|
|
op.f("ix_conversion_guests_hashed_email"),
|
|
"conversion_guests",
|
|
["hashed_email"],
|
|
unique=False,
|
|
)
|
|
|
|
# Create conversions table with new schema
|
|
op.create_table(
|
|
"conversions",
|
|
sa.Column("id", sa.Integer(), nullable=False),
|
|
sa.Column("reservation_id", sa.Integer(), nullable=True),
|
|
sa.Column("customer_id", sa.Integer(), nullable=True),
|
|
sa.Column("hashed_customer_id", sa.Integer(), nullable=True),
|
|
sa.Column("hotel_id", sa.String(), nullable=True),
|
|
sa.Column("guest_id", sa.String(), nullable=True),
|
|
sa.Column("pms_reservation_id", sa.String(), nullable=True),
|
|
sa.Column("reservation_number", sa.String(), nullable=True),
|
|
sa.Column("reservation_date", sa.Date(), nullable=True),
|
|
sa.Column("creation_time", sa.DateTime(timezone=True), nullable=True),
|
|
sa.Column("reservation_type", sa.String(), nullable=True),
|
|
sa.Column("booking_channel", sa.String(), nullable=True),
|
|
sa.Column("advertising_medium", sa.String(), nullable=True),
|
|
sa.Column("advertising_partner", sa.String(), nullable=True),
|
|
sa.Column("advertising_campagne", sa.String(), nullable=True),
|
|
sa.Column("directly_attributable", sa.Boolean(), default=False, nullable=False),
|
|
sa.Column("guest_matched", sa.Boolean(), default=False, nullable=False),
|
|
sa.Column("created_at", sa.DateTime(timezone=True), nullable=True),
|
|
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=True),
|
|
sa.ForeignKeyConstraint(["reservation_id"], ["reservations.id"]),
|
|
sa.ForeignKeyConstraint(["customer_id"], ["customers.id"]),
|
|
sa.ForeignKeyConstraint(["hashed_customer_id"], ["hashed_customers.id"]),
|
|
sa.ForeignKeyConstraint(
|
|
["hotel_id", "guest_id"],
|
|
["conversion_guests.hotel_id", "conversion_guests.guest_id"],
|
|
ondelete="SET NULL",
|
|
),
|
|
sa.PrimaryKeyConstraint("id"),
|
|
)
|
|
op.create_index(
|
|
op.f("ix_conversions_advertising_campagne"),
|
|
"conversions",
|
|
["advertising_campagne"],
|
|
unique=False,
|
|
)
|
|
op.create_index(
|
|
op.f("ix_conversions_advertising_medium"),
|
|
"conversions",
|
|
["advertising_medium"],
|
|
unique=False,
|
|
)
|
|
op.create_index(
|
|
op.f("ix_conversions_advertising_partner"),
|
|
"conversions",
|
|
["advertising_partner"],
|
|
unique=False,
|
|
)
|
|
op.create_index(
|
|
op.f("ix_conversions_customer_id"),
|
|
"conversions",
|
|
["customer_id"],
|
|
unique=False,
|
|
)
|
|
op.create_index(
|
|
op.f("ix_conversions_hashed_customer_id"),
|
|
"conversions",
|
|
["hashed_customer_id"],
|
|
unique=False,
|
|
)
|
|
op.create_index(
|
|
op.f("ix_conversions_hotel_id"),
|
|
"conversions",
|
|
["hotel_id"],
|
|
unique=False,
|
|
)
|
|
op.create_index(
|
|
op.f("ix_conversions_guest_id"),
|
|
"conversions",
|
|
["guest_id"],
|
|
unique=False,
|
|
)
|
|
op.create_index(
|
|
op.f("ix_conversions_pms_reservation_id"),
|
|
"conversions",
|
|
["pms_reservation_id"],
|
|
unique=False,
|
|
)
|
|
op.create_index(
|
|
op.f("ix_conversions_reservation_id"),
|
|
"conversions",
|
|
["reservation_id"],
|
|
unique=False,
|
|
)
|
|
|
|
# Create conversion_rooms table
|
|
op.create_table(
|
|
"conversion_rooms",
|
|
sa.Column("id", sa.Integer(), nullable=False),
|
|
sa.Column("conversion_id", sa.Integer(), nullable=False),
|
|
sa.Column("pms_hotel_reservation_id", sa.String(), nullable=True),
|
|
sa.Column("arrival_date", sa.Date(), nullable=True),
|
|
sa.Column("departure_date", sa.Date(), nullable=True),
|
|
sa.Column("room_status", sa.String(), nullable=True),
|
|
sa.Column("room_type", sa.String(), nullable=True),
|
|
sa.Column("room_number", sa.String(), nullable=True),
|
|
sa.Column("num_adults", sa.Integer(), nullable=True),
|
|
sa.Column("rate_plan_code", sa.String(), nullable=True),
|
|
sa.Column("connected_room_type", sa.String(), nullable=True),
|
|
sa.Column("daily_sales", sa.JSON(), nullable=True),
|
|
sa.Column("total_revenue", sa.Double(), nullable=True),
|
|
sa.Column("created_at", sa.DateTime(timezone=True), nullable=True),
|
|
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=True),
|
|
sa.ForeignKeyConstraint(["conversion_id"], ["conversions.id"]),
|
|
sa.PrimaryKeyConstraint("id"),
|
|
)
|
|
op.create_index(
|
|
op.f("ix_conversion_rooms_arrival_date"),
|
|
"conversion_rooms",
|
|
["arrival_date"],
|
|
unique=False,
|
|
)
|
|
op.create_index(
|
|
op.f("ix_conversion_rooms_conversion_id"),
|
|
"conversion_rooms",
|
|
["conversion_id"],
|
|
unique=False,
|
|
)
|
|
op.create_index(
|
|
op.f("ix_conversion_rooms_departure_date"),
|
|
"conversion_rooms",
|
|
["departure_date"],
|
|
unique=False,
|
|
)
|
|
op.create_index(
|
|
op.f("ix_conversion_rooms_pms_hotel_reservation_id"),
|
|
"conversion_rooms",
|
|
["pms_hotel_reservation_id"],
|
|
unique=False,
|
|
)
|
|
op.create_index(
|
|
op.f("ix_conversion_rooms_room_number"),
|
|
"conversion_rooms",
|
|
["room_number"],
|
|
unique=False,
|
|
)
|
|
|
|
|
|
def downgrade() -> None:
|
|
"""Downgrade schema."""
|
|
op.drop_index(
|
|
op.f("ix_conversion_rooms_room_number"), table_name="conversion_rooms"
|
|
)
|
|
op.drop_index(
|
|
op.f("ix_conversion_rooms_pms_hotel_reservation_id"),
|
|
table_name="conversion_rooms",
|
|
)
|
|
op.drop_index(
|
|
op.f("ix_conversion_rooms_departure_date"), table_name="conversion_rooms"
|
|
)
|
|
op.drop_index(
|
|
op.f("ix_conversion_rooms_conversion_id"), table_name="conversion_rooms"
|
|
)
|
|
op.drop_index(
|
|
op.f("ix_conversion_rooms_arrival_date"), table_name="conversion_rooms"
|
|
)
|
|
op.drop_table("conversion_rooms")
|
|
|
|
op.drop_index(
|
|
op.f("ix_conversions_reservation_id"), table_name="conversions"
|
|
)
|
|
op.drop_index(
|
|
op.f("ix_conversions_pms_reservation_id"), table_name="conversions"
|
|
)
|
|
op.drop_index(
|
|
op.f("ix_conversions_guest_id"), table_name="conversions"
|
|
)
|
|
op.drop_index(
|
|
op.f("ix_conversions_hotel_id"), table_name="conversions"
|
|
)
|
|
op.drop_index(
|
|
op.f("ix_conversions_hashed_customer_id"), table_name="conversions"
|
|
)
|
|
op.drop_index(
|
|
op.f("ix_conversions_customer_id"), table_name="conversions"
|
|
)
|
|
op.drop_index(
|
|
op.f("ix_conversions_advertising_partner"), table_name="conversions"
|
|
)
|
|
op.drop_index(
|
|
op.f("ix_conversions_advertising_medium"), table_name="conversions"
|
|
)
|
|
op.drop_index(
|
|
op.f("ix_conversions_advertising_campagne"), table_name="conversions"
|
|
)
|
|
op.drop_table("conversions")
|
|
|
|
op.drop_index(
|
|
op.f("ix_conversion_guests_hashed_email"), table_name="conversion_guests"
|
|
)
|
|
op.drop_index(
|
|
op.f("ix_conversion_guests_hashed_last_name"), table_name="conversion_guests"
|
|
)
|
|
op.drop_index(
|
|
op.f("ix_conversion_guests_hashed_first_name"), table_name="conversion_guests"
|
|
)
|
|
op.drop_index(
|
|
op.f("ix_conversion_guests_guest_id"), table_name="conversion_guests"
|
|
)
|
|
op.drop_index(
|
|
op.f("ix_conversion_guests_hotel_id"), table_name="conversion_guests"
|
|
)
|
|
op.drop_table("conversion_guests")
|