Stabilize staff concurrency and premium emoji; enable verified Drone deployment
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
40
migrations/versions/20260913_staff_concurrency.py
Normal file
40
migrations/versions/20260913_staff_concurrency.py
Normal file
@@ -0,0 +1,40 @@
|
||||
"""Merge legacy heads, add cashiers, prevent duplicate entries and prize places."""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
revision = "20260913_staff_concurrency"
|
||||
down_revision = ("20260701_perf_indexes", "41aae82e631b")
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
connection = op.get_bind()
|
||||
# Stop safely on ambiguous historical results; never silently delete prizes.
|
||||
checks = (
|
||||
("participations", "lottery_id, account_number", "account_number IS NOT NULL"),
|
||||
("participations", "lottery_id, user_id", "account_number IS NULL AND user_id IS NOT NULL"),
|
||||
("winners", "lottery_id, place", "1=1"),
|
||||
)
|
||||
for table, columns, predicate in checks:
|
||||
duplicate = connection.execute(sa.text(
|
||||
f"SELECT 1 FROM {table} WHERE {predicate} GROUP BY {columns} HAVING COUNT(*) > 1 LIMIT 1"
|
||||
)).first()
|
||||
if duplicate:
|
||||
raise RuntimeError(f"Duplicate {table} ({columns}); review duplicates before migrating. No data removed.")
|
||||
op.add_column("users", sa.Column("is_cashier", sa.Boolean(), server_default=sa.false(), nullable=False))
|
||||
with op.batch_alter_table("participations") as batch:
|
||||
batch.create_unique_constraint("uq_participation_account", ["lottery_id", "account_number"])
|
||||
op.create_index("uq_participation_user", "participations", ["lottery_id", "user_id"], unique=True,
|
||||
postgresql_where=sa.text("account_number IS NULL"), sqlite_where=sa.text("account_number IS NULL"))
|
||||
with op.batch_alter_table("winners") as batch:
|
||||
batch.create_unique_constraint("uq_winner_place", ["lottery_id", "place"])
|
||||
|
||||
|
||||
def downgrade():
|
||||
with op.batch_alter_table("winners") as batch:
|
||||
batch.drop_constraint("uq_winner_place", type_="unique")
|
||||
op.drop_index("uq_participation_user", table_name="participations")
|
||||
with op.batch_alter_table("participations") as batch:
|
||||
batch.drop_constraint("uq_participation_account", type_="unique")
|
||||
op.drop_column("users", "is_cashier")
|
||||
Reference in New Issue
Block a user