Fix migration transaction poisoning: ADD COLUMN IF NOT EXISTS
Migrations used try/except around ADD COLUMN inside a single engine.begin() block. When a 'column already exists' error was caught, asyncpg left the transaction in aborted state, causing all subsequent DDL in the block to fail with InFailedSQLTransactionError. Replace with IF NOT EXISTS to prevent the error entirely. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
e7e1fda9f6
commit
bc874ac9ff
25 changed files with 302 additions and 302 deletions
|
|
@ -16,7 +16,7 @@ async def run_migration():
|
|||
"""Add admin_restricted_pages column to kitchen_settings table."""
|
||||
logger.info("Running admin restricted pages migration...")
|
||||
|
||||
sql = "ALTER TABLE kitchen_settings ADD COLUMN admin_restricted_pages TEXT"
|
||||
sql = "ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS admin_restricted_pages TEXT"
|
||||
|
||||
try:
|
||||
async with engine.begin() as conn:
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ async def migrate():
|
|||
await conn.execute(text(
|
||||
"""
|
||||
ALTER TABLE kitchen_settings
|
||||
ADD COLUMN forecast_api_url VARCHAR(500)
|
||||
ADD COLUMN IF NOT EXISTS forecast_api_url VARCHAR(500)
|
||||
"""
|
||||
))
|
||||
print("+ Added forecast_api_url column")
|
||||
|
|
@ -34,7 +34,7 @@ async def migrate():
|
|||
await conn.execute(text(
|
||||
"""
|
||||
ALTER TABLE kitchen_settings
|
||||
ADD COLUMN forecast_api_key VARCHAR(500)
|
||||
ADD COLUMN IF NOT EXISTS forecast_api_key VARCHAR(500)
|
||||
"""
|
||||
))
|
||||
print("+ Added forecast_api_key column")
|
||||
|
|
@ -49,7 +49,7 @@ async def migrate():
|
|||
await conn.execute(text(
|
||||
"""
|
||||
ALTER TABLE kitchen_settings
|
||||
ADD COLUMN budget_gp_target NUMERIC(5,2) DEFAULT 65.00
|
||||
ADD COLUMN IF NOT EXISTS budget_gp_target NUMERIC(5,2) DEFAULT 65.00
|
||||
"""
|
||||
))
|
||||
print("+ Added budget_gp_target column")
|
||||
|
|
@ -64,7 +64,7 @@ async def migrate():
|
|||
await conn.execute(text(
|
||||
"""
|
||||
ALTER TABLE kitchen_settings
|
||||
ADD COLUMN budget_lookback_weeks INTEGER DEFAULT 4
|
||||
ADD COLUMN IF NOT EXISTS budget_lookback_weeks INTEGER DEFAULT 4
|
||||
"""
|
||||
))
|
||||
print("+ Added budget_lookback_weeks column")
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ async def migrate():
|
|||
# Add cost_distribution_max_days to kitchen_settings
|
||||
try:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN cost_distribution_max_days INTEGER DEFAULT 90"
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS cost_distribution_max_days INTEGER DEFAULT 90"
|
||||
))
|
||||
print("+ Added cost_distribution_max_days to kitchen_settings")
|
||||
except Exception as e:
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE invoices ADD COLUMN notes TEXT"
|
||||
"ALTER TABLE invoices ADD COLUMN IF NOT EXISTS notes TEXT"
|
||||
))
|
||||
logger.info("Added notes column to invoices")
|
||||
except Exception as e:
|
||||
|
|
@ -39,7 +39,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE invoices ADD COLUMN dext_sent_at TIMESTAMP"
|
||||
"ALTER TABLE invoices ADD COLUMN IF NOT EXISTS dext_sent_at TIMESTAMP"
|
||||
))
|
||||
logger.info("Added dext_sent_at column to invoices")
|
||||
except Exception as e:
|
||||
|
|
@ -52,7 +52,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE invoices ADD COLUMN dext_sent_by_user_id INTEGER REFERENCES users(id)"
|
||||
"ALTER TABLE invoices ADD COLUMN IF NOT EXISTS dext_sent_by_user_id INTEGER REFERENCES users(id)"
|
||||
))
|
||||
logger.info("Added dext_sent_by_user_id column to invoices")
|
||||
except Exception as e:
|
||||
|
|
@ -67,7 +67,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN smtp_host VARCHAR(255)"
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS smtp_host VARCHAR(255)"
|
||||
))
|
||||
logger.info("Added smtp_host column to kitchen_settings")
|
||||
except Exception as e:
|
||||
|
|
@ -80,7 +80,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN smtp_port INTEGER DEFAULT 587"
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS smtp_port INTEGER DEFAULT 587"
|
||||
))
|
||||
logger.info("Added smtp_port column to kitchen_settings")
|
||||
except Exception as e:
|
||||
|
|
@ -93,7 +93,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN smtp_username VARCHAR(255)"
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS smtp_username VARCHAR(255)"
|
||||
))
|
||||
logger.info("Added smtp_username column to kitchen_settings")
|
||||
except Exception as e:
|
||||
|
|
@ -106,7 +106,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN smtp_password VARCHAR(500)"
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS smtp_password VARCHAR(500)"
|
||||
))
|
||||
logger.info("Added smtp_password column to kitchen_settings")
|
||||
except Exception as e:
|
||||
|
|
@ -119,7 +119,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN smtp_use_tls BOOLEAN DEFAULT TRUE"
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS smtp_use_tls BOOLEAN DEFAULT TRUE"
|
||||
))
|
||||
logger.info("Added smtp_use_tls column to kitchen_settings")
|
||||
except Exception as e:
|
||||
|
|
@ -132,7 +132,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN smtp_from_email VARCHAR(255)"
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS smtp_from_email VARCHAR(255)"
|
||||
))
|
||||
logger.info("Added smtp_from_email column to kitchen_settings")
|
||||
except Exception as e:
|
||||
|
|
@ -145,7 +145,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN smtp_from_name VARCHAR(255) DEFAULT 'Kitchen Invoice System'"
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS smtp_from_name VARCHAR(255) DEFAULT 'Kitchen Invoice System'"
|
||||
))
|
||||
logger.info("Added smtp_from_name column to kitchen_settings")
|
||||
except Exception as e:
|
||||
|
|
@ -160,7 +160,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN dext_email VARCHAR(255)"
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS dext_email VARCHAR(255)"
|
||||
))
|
||||
logger.info("Added dext_email column to kitchen_settings")
|
||||
except Exception as e:
|
||||
|
|
@ -173,7 +173,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN dext_include_notes BOOLEAN DEFAULT TRUE"
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS dext_include_notes BOOLEAN DEFAULT TRUE"
|
||||
))
|
||||
logger.info("Added dext_include_notes column to kitchen_settings")
|
||||
except Exception as e:
|
||||
|
|
@ -186,7 +186,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN dext_include_non_stock BOOLEAN DEFAULT TRUE"
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS dext_include_non_stock BOOLEAN DEFAULT TRUE"
|
||||
))
|
||||
logger.info("Added dext_include_non_stock column to kitchen_settings")
|
||||
except Exception as e:
|
||||
|
|
@ -199,7 +199,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN dext_auto_send_enabled BOOLEAN DEFAULT FALSE"
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS dext_auto_send_enabled BOOLEAN DEFAULT FALSE"
|
||||
))
|
||||
logger.info("Added dext_auto_send_enabled column to kitchen_settings")
|
||||
except Exception as e:
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ async def migrate():
|
|||
await conn.execute(text(
|
||||
"""
|
||||
ALTER TABLE kitchen_settings
|
||||
ADD COLUMN dext_manual_send_enabled BOOLEAN DEFAULT TRUE
|
||||
ADD COLUMN IF NOT EXISTS dext_manual_send_enabled BOOLEAN DEFAULT TRUE
|
||||
"""
|
||||
))
|
||||
print("✓ Added dext_manual_send_enabled column")
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ async def run_migration():
|
|||
logger.info("Adding 'public_hash' column to dispute_attachments table")
|
||||
await conn.execute(text("""
|
||||
ALTER TABLE dispute_attachments
|
||||
ADD COLUMN public_hash VARCHAR(64) UNIQUE;
|
||||
ADD COLUMN IF NOT EXISTS public_hash VARCHAR(64) UNIQUE;
|
||||
"""))
|
||||
|
||||
# Create index for fast lookups
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
"""Add gross_sell_price column to recipes table."""
|
||||
import logging
|
||||
from sqlalchemy import text
|
||||
from database import engine
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def migrate():
|
||||
async with engine.begin() as conn:
|
||||
result = await conn.execute(text(
|
||||
"SELECT column_name FROM information_schema.columns "
|
||||
"WHERE table_name = 'recipes' AND column_name = 'gross_sell_price'"
|
||||
))
|
||||
if result.scalar_one_or_none():
|
||||
logger.info("recipes.gross_sell_price already exists, skipping")
|
||||
return
|
||||
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE recipes ADD COLUMN gross_sell_price NUMERIC(10,2) DEFAULT NULL"
|
||||
))
|
||||
logger.info("Added recipes.gross_sell_price column")
|
||||
"""Add gross_sell_price column to recipes table."""
|
||||
import logging
|
||||
from sqlalchemy import text
|
||||
from database import engine
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def migrate():
|
||||
async with engine.begin() as conn:
|
||||
result = await conn.execute(text(
|
||||
"SELECT column_name FROM information_schema.columns "
|
||||
"WHERE table_name = 'recipes' AND column_name = 'gross_sell_price'"
|
||||
))
|
||||
if result.scalar_one_or_none():
|
||||
logger.info("recipes.gross_sell_price already exists, skipping")
|
||||
return
|
||||
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE recipes ADD COLUMN IF NOT EXISTS gross_sell_price NUMERIC(10,2) DEFAULT NULL"
|
||||
))
|
||||
logger.info("Added recipes.gross_sell_price column")
|
||||
|
|
|
|||
|
|
@ -22,11 +22,11 @@ async def run_migration():
|
|||
|
||||
# Run each migration in its own transaction
|
||||
migrations = [
|
||||
"ALTER TABLE invoices ADD COLUMN document_type VARCHAR(50) DEFAULT 'invoice'",
|
||||
"ALTER TABLE invoices ADD COLUMN order_number VARCHAR(100)",
|
||||
"ALTER TABLE invoices ADD COLUMN duplicate_status VARCHAR(50)",
|
||||
"ALTER TABLE invoices ADD COLUMN duplicate_of_id INTEGER REFERENCES invoices(id)",
|
||||
"ALTER TABLE invoices ADD COLUMN related_document_id INTEGER REFERENCES invoices(id)",
|
||||
"ALTER TABLE invoices ADD COLUMN IF NOT EXISTS document_type VARCHAR(50) DEFAULT 'invoice'",
|
||||
"ALTER TABLE invoices ADD COLUMN IF NOT EXISTS order_number VARCHAR(100)",
|
||||
"ALTER TABLE invoices ADD COLUMN IF NOT EXISTS duplicate_status VARCHAR(50)",
|
||||
"ALTER TABLE invoices ADD COLUMN IF NOT EXISTS duplicate_of_id INTEGER REFERENCES invoices(id)",
|
||||
"ALTER TABLE invoices ADD COLUMN IF NOT EXISTS related_document_id INTEGER REFERENCES invoices(id)",
|
||||
]
|
||||
|
||||
for sql in migrations:
|
||||
|
|
@ -76,7 +76,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE suppliers ADD COLUMN aliases JSON DEFAULT '[]'"
|
||||
"ALTER TABLE suppliers ADD COLUMN IF NOT EXISTS aliases JSON DEFAULT '[]'"
|
||||
))
|
||||
logger.info("Added aliases column to suppliers")
|
||||
except Exception as e:
|
||||
|
|
@ -89,7 +89,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE invoices ADD COLUMN net_total NUMERIC(10, 2)"
|
||||
"ALTER TABLE invoices ADD COLUMN IF NOT EXISTS net_total NUMERIC(10, 2)"
|
||||
))
|
||||
logger.info("Added net_total column to invoices")
|
||||
except Exception as e:
|
||||
|
|
@ -102,7 +102,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE line_items ADD COLUMN is_non_stock BOOLEAN DEFAULT FALSE"
|
||||
"ALTER TABLE line_items ADD COLUMN IF NOT EXISTS is_non_stock BOOLEAN DEFAULT FALSE"
|
||||
))
|
||||
logger.info("Added is_non_stock column to line_items")
|
||||
except Exception as e:
|
||||
|
|
@ -115,7 +115,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE invoices ADD COLUMN vendor_name VARCHAR(255)"
|
||||
"ALTER TABLE invoices ADD COLUMN IF NOT EXISTS vendor_name VARCHAR(255)"
|
||||
))
|
||||
logger.info("Added vendor_name column to invoices")
|
||||
except Exception as e:
|
||||
|
|
@ -128,7 +128,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE invoices ADD COLUMN ocr_raw_json TEXT"
|
||||
"ALTER TABLE invoices ADD COLUMN IF NOT EXISTS ocr_raw_json TEXT"
|
||||
))
|
||||
logger.info("Added ocr_raw_json column to invoices")
|
||||
except Exception as e:
|
||||
|
|
@ -141,7 +141,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE invoices ADD COLUMN supplier_match_type VARCHAR(20)"
|
||||
"ALTER TABLE invoices ADD COLUMN IF NOT EXISTS supplier_match_type VARCHAR(20)"
|
||||
))
|
||||
logger.info("Added supplier_match_type column to invoices")
|
||||
except Exception as e:
|
||||
|
|
@ -189,7 +189,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE line_items ADD COLUMN unit VARCHAR(50)"
|
||||
"ALTER TABLE line_items ADD COLUMN IF NOT EXISTS unit VARCHAR(50)"
|
||||
))
|
||||
logger.info("Added unit column to line_items")
|
||||
except Exception as e:
|
||||
|
|
@ -202,7 +202,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE line_items ADD COLUMN order_quantity NUMERIC(10, 3)"
|
||||
"ALTER TABLE line_items ADD COLUMN IF NOT EXISTS order_quantity NUMERIC(10, 3)"
|
||||
))
|
||||
logger.info("Added order_quantity column to line_items")
|
||||
except Exception as e:
|
||||
|
|
@ -215,7 +215,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE line_items ADD COLUMN tax_rate VARCHAR(50)"
|
||||
"ALTER TABLE line_items ADD COLUMN IF NOT EXISTS tax_rate VARCHAR(50)"
|
||||
))
|
||||
logger.info("Added tax_rate column to line_items")
|
||||
except Exception as e:
|
||||
|
|
@ -228,7 +228,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE line_items ADD COLUMN tax_amount NUMERIC(10, 2)"
|
||||
"ALTER TABLE line_items ADD COLUMN IF NOT EXISTS tax_amount NUMERIC(10, 2)"
|
||||
))
|
||||
logger.info("Added tax_amount column to line_items")
|
||||
except Exception as e:
|
||||
|
|
@ -241,7 +241,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE line_items ADD COLUMN raw_content TEXT"
|
||||
"ALTER TABLE line_items ADD COLUMN IF NOT EXISTS raw_content TEXT"
|
||||
))
|
||||
logger.info("Added raw_content column to line_items")
|
||||
except Exception as e:
|
||||
|
|
@ -254,7 +254,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE line_items ADD COLUMN pack_quantity INTEGER"
|
||||
"ALTER TABLE line_items ADD COLUMN IF NOT EXISTS pack_quantity INTEGER"
|
||||
))
|
||||
logger.info("Added pack_quantity column to line_items")
|
||||
except Exception as e:
|
||||
|
|
@ -267,7 +267,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE line_items ADD COLUMN unit_size NUMERIC(10, 3)"
|
||||
"ALTER TABLE line_items ADD COLUMN IF NOT EXISTS unit_size NUMERIC(10, 3)"
|
||||
))
|
||||
logger.info("Added unit_size column to line_items")
|
||||
except Exception as e:
|
||||
|
|
@ -280,7 +280,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE line_items ADD COLUMN unit_size_type VARCHAR(10)"
|
||||
"ALTER TABLE line_items ADD COLUMN IF NOT EXISTS unit_size_type VARCHAR(10)"
|
||||
))
|
||||
logger.info("Added unit_size_type column to line_items")
|
||||
except Exception as e:
|
||||
|
|
@ -293,7 +293,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE line_items ADD COLUMN portions_per_unit INTEGER DEFAULT 1"
|
||||
"ALTER TABLE line_items ADD COLUMN IF NOT EXISTS portions_per_unit INTEGER DEFAULT 1"
|
||||
))
|
||||
logger.info("Added portions_per_unit column to line_items")
|
||||
except Exception as e:
|
||||
|
|
@ -306,7 +306,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE line_items ADD COLUMN cost_per_item NUMERIC(10, 4)"
|
||||
"ALTER TABLE line_items ADD COLUMN IF NOT EXISTS cost_per_item NUMERIC(10, 4)"
|
||||
))
|
||||
logger.info("Added cost_per_item column to line_items")
|
||||
except Exception as e:
|
||||
|
|
@ -319,7 +319,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE line_items ADD COLUMN cost_per_portion NUMERIC(10, 4)"
|
||||
"ALTER TABLE line_items ADD COLUMN IF NOT EXISTS cost_per_portion NUMERIC(10, 4)"
|
||||
))
|
||||
logger.info("Added cost_per_portion column to line_items")
|
||||
except Exception as e:
|
||||
|
|
@ -384,7 +384,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE product_definitions ADD COLUMN saved_by_user_id INTEGER REFERENCES users(id)"
|
||||
"ALTER TABLE product_definitions ADD COLUMN IF NOT EXISTS saved_by_user_id INTEGER REFERENCES users(id)"
|
||||
))
|
||||
logger.info("Added saved_by_user_id column to product_definitions")
|
||||
except Exception as e:
|
||||
|
|
@ -397,7 +397,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE product_definitions ADD COLUMN source_invoice_id INTEGER REFERENCES invoices(id) ON DELETE SET NULL"
|
||||
"ALTER TABLE product_definitions ADD COLUMN IF NOT EXISTS source_invoice_id INTEGER REFERENCES invoices(id) ON DELETE SET NULL"
|
||||
))
|
||||
logger.info("Added source_invoice_id column to product_definitions")
|
||||
except Exception as e:
|
||||
|
|
@ -410,7 +410,7 @@ async def run_migration():
|
|||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE product_definitions ADD COLUMN source_invoice_number VARCHAR(100)"
|
||||
"ALTER TABLE product_definitions ADD COLUMN IF NOT EXISTS source_invoice_number VARCHAR(100)"
|
||||
))
|
||||
logger.info("Added source_invoice_number column to product_definitions")
|
||||
except Exception as e:
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ async def migrate():
|
|||
for col_name, col_type in COLUMNS:
|
||||
try:
|
||||
await conn.execute(text(
|
||||
f"ALTER TABLE kitchen_settings ADD COLUMN {col_name} {col_type}"
|
||||
f"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS {col_name} {col_type}"
|
||||
))
|
||||
print(f"+ Added {col_name} column to kitchen_settings")
|
||||
except Exception as e:
|
||||
|
|
|
|||
|
|
@ -26,9 +26,9 @@ async def run_migration():
|
|||
|
||||
# Add arrival tracking columns to newbook_daily_occupancy table
|
||||
arrival_columns = [
|
||||
"ALTER TABLE newbook_daily_occupancy ADD COLUMN arrival_count INTEGER",
|
||||
"ALTER TABLE newbook_daily_occupancy ADD COLUMN arrival_booking_ids JSONB",
|
||||
"ALTER TABLE newbook_daily_occupancy ADD COLUMN arrival_booking_details JSONB",
|
||||
"ALTER TABLE newbook_daily_occupancy ADD COLUMN IF NOT EXISTS arrival_count INTEGER",
|
||||
"ALTER TABLE newbook_daily_occupancy ADD COLUMN IF NOT EXISTS arrival_booking_ids JSONB",
|
||||
"ALTER TABLE newbook_daily_occupancy ADD COLUMN IF NOT EXISTS arrival_booking_details JSONB",
|
||||
]
|
||||
|
||||
for sql in arrival_columns:
|
||||
|
|
|
|||
|
|
@ -23,15 +23,15 @@ async def run_migration():
|
|||
|
||||
# Add Newbook columns to kitchen_settings table
|
||||
settings_columns = [
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN newbook_api_username VARCHAR(255)",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN newbook_api_password VARCHAR(500)",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN newbook_api_key VARCHAR(500)",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN newbook_api_region VARCHAR(10)",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN newbook_instance_id VARCHAR(100)",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN newbook_last_sync TIMESTAMP",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN newbook_auto_sync_enabled BOOLEAN DEFAULT FALSE",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN newbook_breakfast_gl_codes VARCHAR(500)",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN newbook_dinner_gl_codes VARCHAR(500)",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS newbook_api_username VARCHAR(255)",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS newbook_api_password VARCHAR(500)",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS newbook_api_key VARCHAR(500)",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS newbook_api_region VARCHAR(10)",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS newbook_instance_id VARCHAR(100)",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS newbook_last_sync TIMESTAMP",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS newbook_auto_sync_enabled BOOLEAN DEFAULT FALSE",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS newbook_breakfast_gl_codes VARCHAR(500)",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS newbook_dinner_gl_codes VARCHAR(500)",
|
||||
]
|
||||
|
||||
for sql in settings_columns:
|
||||
|
|
@ -163,7 +163,7 @@ async def run_migration():
|
|||
# Add room_count column if it doesn't exist
|
||||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text("ALTER TABLE newbook_room_categories ADD COLUMN room_count INTEGER DEFAULT 0"))
|
||||
await conn.execute(text("ALTER TABLE newbook_room_categories ADD COLUMN IF NOT EXISTS room_count INTEGER DEFAULT 0"))
|
||||
logger.info("Added room_count column to newbook_room_categories")
|
||||
except Exception as e:
|
||||
if "already exists" in str(e).lower() or "duplicate column" in str(e).lower():
|
||||
|
|
|
|||
|
|
@ -1,28 +1,28 @@
|
|||
"""Add batch_output_type, batch_yield_qty, batch_yield_unit to recipes table."""
|
||||
import logging
|
||||
from sqlalchemy import text
|
||||
from database import engine
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def migrate():
|
||||
async with engine.begin() as conn:
|
||||
result = await conn.execute(text(
|
||||
"SELECT column_name FROM information_schema.columns "
|
||||
"WHERE table_name = 'recipes' AND column_name = 'batch_output_type'"
|
||||
))
|
||||
if result.scalar_one_or_none():
|
||||
logger.info("recipes.batch_output_type already exists, skipping")
|
||||
return
|
||||
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE recipes ADD COLUMN batch_output_type VARCHAR(20) NOT NULL DEFAULT 'portions'"
|
||||
))
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE recipes ADD COLUMN batch_yield_qty NUMERIC(10,3) DEFAULT NULL"
|
||||
))
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE recipes ADD COLUMN batch_yield_unit VARCHAR(10) DEFAULT NULL"
|
||||
))
|
||||
logger.info("Added batch output type columns to recipes")
|
||||
"""Add batch_output_type, batch_yield_qty, batch_yield_unit to recipes table."""
|
||||
import logging
|
||||
from sqlalchemy import text
|
||||
from database import engine
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def migrate():
|
||||
async with engine.begin() as conn:
|
||||
result = await conn.execute(text(
|
||||
"SELECT column_name FROM information_schema.columns "
|
||||
"WHERE table_name = 'recipes' AND column_name = 'batch_output_type'"
|
||||
))
|
||||
if result.scalar_one_or_none():
|
||||
logger.info("recipes.batch_output_type already exists, skipping")
|
||||
return
|
||||
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE recipes ADD COLUMN IF NOT EXISTS batch_output_type VARCHAR(20) NOT NULL DEFAULT 'portions'"
|
||||
))
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE recipes ADD COLUMN IF NOT EXISTS batch_yield_qty NUMERIC(10,3) DEFAULT NULL"
|
||||
))
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE recipes ADD COLUMN IF NOT EXISTS batch_yield_unit VARCHAR(10) DEFAULT NULL"
|
||||
))
|
||||
logger.info("Added batch output type columns to recipes")
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
"""Add unit column to recipe_ingredients table for display unit override."""
|
||||
import logging
|
||||
from sqlalchemy import text
|
||||
from database import engine
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def migrate():
|
||||
async with engine.begin() as conn:
|
||||
result = await conn.execute(text(
|
||||
"SELECT column_name FROM information_schema.columns "
|
||||
"WHERE table_name = 'recipe_ingredients' AND column_name = 'unit'"
|
||||
))
|
||||
if result.scalar_one_or_none():
|
||||
logger.info("recipe_ingredients.unit already exists, skipping")
|
||||
return
|
||||
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE recipe_ingredients ADD COLUMN unit VARCHAR(10) DEFAULT NULL"
|
||||
))
|
||||
logger.info("Added unit column to recipe_ingredients")
|
||||
"""Add unit column to recipe_ingredients table for display unit override."""
|
||||
import logging
|
||||
from sqlalchemy import text
|
||||
from database import engine
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def migrate():
|
||||
async with engine.begin() as conn:
|
||||
result = await conn.execute(text(
|
||||
"SELECT column_name FROM information_schema.columns "
|
||||
"WHERE table_name = 'recipe_ingredients' AND column_name = 'unit'"
|
||||
))
|
||||
if result.scalar_one_or_none():
|
||||
logger.info("recipe_ingredients.unit already exists, skipping")
|
||||
return
|
||||
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE recipe_ingredients ADD COLUMN IF NOT EXISTS unit VARCHAR(10) DEFAULT NULL"
|
||||
))
|
||||
logger.info("Added unit column to recipe_ingredients")
|
||||
|
|
|
|||
|
|
@ -1,33 +1,33 @@
|
|||
"""Move yield_percent from ingredients to recipe_ingredients (per-use yield)."""
|
||||
import logging
|
||||
from sqlalchemy import text
|
||||
from database import engine
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def migrate():
|
||||
async with engine.begin() as conn:
|
||||
# Check if column already exists
|
||||
result = await conn.execute(text(
|
||||
"SELECT column_name FROM information_schema.columns "
|
||||
"WHERE table_name = 'recipe_ingredients' AND column_name = 'yield_percent'"
|
||||
))
|
||||
if result.scalar_one_or_none():
|
||||
logger.info("recipe_ingredients.yield_percent already exists, skipping")
|
||||
return
|
||||
|
||||
# Add yield_percent to recipe_ingredients with default 100
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE recipe_ingredients ADD COLUMN yield_percent NUMERIC(5,2) DEFAULT 100.00 NOT NULL"
|
||||
))
|
||||
logger.info("Added recipe_ingredients.yield_percent column")
|
||||
|
||||
# Populate from existing ingredient yields
|
||||
await conn.execute(text(
|
||||
"UPDATE recipe_ingredients ri "
|
||||
"SET yield_percent = i.yield_percent "
|
||||
"FROM ingredients i "
|
||||
"WHERE ri.ingredient_id = i.id AND i.yield_percent != 100.00"
|
||||
))
|
||||
logger.info("Populated recipe_ingredients.yield_percent from existing ingredient values")
|
||||
"""Move yield_percent from ingredients to recipe_ingredients (per-use yield)."""
|
||||
import logging
|
||||
from sqlalchemy import text
|
||||
from database import engine
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def migrate():
|
||||
async with engine.begin() as conn:
|
||||
# Check if column already exists
|
||||
result = await conn.execute(text(
|
||||
"SELECT column_name FROM information_schema.columns "
|
||||
"WHERE table_name = 'recipe_ingredients' AND column_name = 'yield_percent'"
|
||||
))
|
||||
if result.scalar_one_or_none():
|
||||
logger.info("recipe_ingredients.yield_percent already exists, skipping")
|
||||
return
|
||||
|
||||
# Add yield_percent to recipe_ingredients with default 100
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE recipe_ingredients ADD COLUMN IF NOT EXISTS yield_percent NUMERIC(5,2) DEFAULT 100.00 NOT NULL"
|
||||
))
|
||||
logger.info("Added recipe_ingredients.yield_percent column")
|
||||
|
||||
# Populate from existing ingredient yields
|
||||
await conn.execute(text(
|
||||
"UPDATE recipe_ingredients ri "
|
||||
"SET yield_percent = i.yield_percent "
|
||||
"FROM ingredients i "
|
||||
"WHERE ri.ingredient_id = i.id AND i.yield_percent != 100.00"
|
||||
))
|
||||
logger.info("Populated recipe_ingredients.yield_percent from existing ingredient values")
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ async def run_migration():
|
|||
logger.info("Running Resos arrival widget filter migration...")
|
||||
|
||||
# Add arrival widget service filter column
|
||||
sql = "ALTER TABLE kitchen_settings ADD COLUMN resos_arrival_widget_service_filter VARCHAR(255)"
|
||||
sql = "ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS resos_arrival_widget_service_filter VARCHAR(255)"
|
||||
|
||||
try:
|
||||
async with engine.begin() as conn:
|
||||
|
|
|
|||
|
|
@ -23,16 +23,16 @@ async def run_migration():
|
|||
|
||||
# Add Resos columns to kitchen_settings table
|
||||
settings_columns = [
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN resos_api_key VARCHAR(500)",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN resos_last_sync TIMESTAMP",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN resos_auto_sync_enabled BOOLEAN DEFAULT FALSE",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN resos_large_group_threshold INTEGER DEFAULT 8",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN resos_note_keywords TEXT",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN resos_allergy_keywords TEXT",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN resos_custom_field_mapping JSONB",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN resos_opening_hours_mapping JSONB",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN resos_restaurant_table_entities TEXT",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN resos_flag_icon_mapping JSONB",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS resos_api_key VARCHAR(500)",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS resos_last_sync TIMESTAMP",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS resos_auto_sync_enabled BOOLEAN DEFAULT FALSE",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS resos_large_group_threshold INTEGER DEFAULT 8",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS resos_note_keywords TEXT",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS resos_allergy_keywords TEXT",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS resos_custom_field_mapping JSONB",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS resos_opening_hours_mapping JSONB",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS resos_restaurant_table_entities TEXT",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS resos_flag_icon_mapping JSONB",
|
||||
]
|
||||
|
||||
for sql in settings_columns:
|
||||
|
|
@ -154,7 +154,7 @@ async def run_migration():
|
|||
# Add unique_flag_types column to resos_daily_stats if it doesn't exist
|
||||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text("ALTER TABLE resos_daily_stats ADD COLUMN unique_flag_types JSONB"))
|
||||
await conn.execute(text("ALTER TABLE resos_daily_stats ADD COLUMN IF NOT EXISTS unique_flag_types JSONB"))
|
||||
logger.info("Added unique_flag_types column to resos_daily_stats")
|
||||
except Exception as e:
|
||||
if "already exists" in str(e).lower() or "duplicate column" in str(e).lower():
|
||||
|
|
@ -165,7 +165,7 @@ async def run_migration():
|
|||
# Add table_name column to resos_bookings (Phase 8.1)
|
||||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text("ALTER TABLE resos_bookings ADD COLUMN table_name VARCHAR(100)"))
|
||||
await conn.execute(text("ALTER TABLE resos_bookings ADD COLUMN IF NOT EXISTS table_name VARCHAR(100)"))
|
||||
logger.info("Added table_name column to resos_bookings")
|
||||
except Exception as e:
|
||||
if "already exists" in str(e).lower() or "duplicate column" in str(e).lower():
|
||||
|
|
@ -176,7 +176,7 @@ async def run_migration():
|
|||
# Add GL code columns for food/beverage split (Phase 8.1)
|
||||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text("ALTER TABLE kitchen_settings ADD COLUMN sambapos_food_gl_codes TEXT"))
|
||||
await conn.execute(text("ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS sambapos_food_gl_codes TEXT"))
|
||||
logger.info("Added sambapos_food_gl_codes column to kitchen_settings")
|
||||
except Exception as e:
|
||||
if "already exists" in str(e).lower() or "duplicate column" in str(e).lower():
|
||||
|
|
@ -186,7 +186,7 @@ async def run_migration():
|
|||
|
||||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text("ALTER TABLE kitchen_settings ADD COLUMN sambapos_beverage_gl_codes TEXT"))
|
||||
await conn.execute(text("ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS sambapos_beverage_gl_codes TEXT"))
|
||||
logger.info("Added sambapos_beverage_gl_codes column to kitchen_settings")
|
||||
except Exception as e:
|
||||
if "already exists" in str(e).lower() or "duplicate column" in str(e).lower():
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ async def run_migration():
|
|||
logger.info("Running Resos manual breakfast configuration migration...")
|
||||
|
||||
migrations = [
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN resos_enable_manual_breakfast BOOLEAN DEFAULT FALSE",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN resos_manual_breakfast_periods JSONB"
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS resos_enable_manual_breakfast BOOLEAN DEFAULT FALSE",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS resos_manual_breakfast_periods JSONB"
|
||||
]
|
||||
|
||||
async with engine.begin() as conn:
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ async def run_migration():
|
|||
logger.info("Running SambaPOS excluded items migration...")
|
||||
|
||||
# Add column for excluded items (TEXT to allow for many items with long names)
|
||||
sql = "ALTER TABLE kitchen_settings ADD COLUMN sambapos_excluded_items TEXT"
|
||||
sql = "ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS sambapos_excluded_items TEXT"
|
||||
|
||||
try:
|
||||
async with engine.begin() as conn:
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
"""Add sambapos_portion_name column to recipes table."""
|
||||
import logging
|
||||
from sqlalchemy import text
|
||||
from database import engine
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def migrate():
|
||||
async with engine.begin() as conn:
|
||||
result = await conn.execute(text(
|
||||
"SELECT column_name FROM information_schema.columns "
|
||||
"WHERE table_name = 'recipes' AND column_name = 'sambapos_portion_name'"
|
||||
))
|
||||
if result.scalar_one_or_none():
|
||||
logger.info("recipes.sambapos_portion_name already exists, skipping")
|
||||
return
|
||||
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE recipes ADD COLUMN sambapos_portion_name VARCHAR(255) DEFAULT NULL"
|
||||
))
|
||||
logger.info("Added recipes.sambapos_portion_name column")
|
||||
"""Add sambapos_portion_name column to recipes table."""
|
||||
import logging
|
||||
from sqlalchemy import text
|
||||
from database import engine
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def migrate():
|
||||
async with engine.begin() as conn:
|
||||
result = await conn.execute(text(
|
||||
"SELECT column_name FROM information_schema.columns "
|
||||
"WHERE table_name = 'recipes' AND column_name = 'sambapos_portion_name'"
|
||||
))
|
||||
if result.scalar_one_or_none():
|
||||
logger.info("recipes.sambapos_portion_name already exists, skipping")
|
||||
return
|
||||
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE recipes ADD COLUMN IF NOT EXISTS sambapos_portion_name VARCHAR(255) DEFAULT NULL"
|
||||
))
|
||||
logger.info("Added recipes.sambapos_portion_name column")
|
||||
|
|
|
|||
|
|
@ -18,12 +18,12 @@ async def run_migration():
|
|||
|
||||
# Add SambaPOS columns to kitchen_settings table
|
||||
settings_columns = [
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN sambapos_db_host VARCHAR(255)",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN sambapos_db_port INTEGER DEFAULT 1433",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN sambapos_db_name VARCHAR(255)",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN sambapos_db_username VARCHAR(255)",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN sambapos_db_password VARCHAR(500)",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN sambapos_tracked_categories VARCHAR(1000)",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS sambapos_db_host VARCHAR(255)",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS sambapos_db_port INTEGER DEFAULT 1433",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS sambapos_db_name VARCHAR(255)",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS sambapos_db_username VARCHAR(255)",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS sambapos_db_password VARCHAR(500)",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS sambapos_tracked_categories VARCHAR(1000)",
|
||||
]
|
||||
|
||||
for sql in settings_columns:
|
||||
|
|
|
|||
|
|
@ -1,23 +1,23 @@
|
|||
"""Add title column to recipe_steps table."""
|
||||
import logging
|
||||
from sqlalchemy import text
|
||||
from database import engine
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def migrate():
|
||||
async with engine.begin() as conn:
|
||||
# Check if column already exists
|
||||
result = await conn.execute(text(
|
||||
"SELECT column_name FROM information_schema.columns "
|
||||
"WHERE table_name = 'recipe_steps' AND column_name = 'title'"
|
||||
))
|
||||
if result.scalar_one_or_none():
|
||||
logger.info("recipe_steps.title already exists, skipping")
|
||||
return
|
||||
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE recipe_steps ADD COLUMN title VARCHAR(255) DEFAULT NULL"
|
||||
))
|
||||
logger.info("Added recipe_steps.title column")
|
||||
"""Add title column to recipe_steps table."""
|
||||
import logging
|
||||
from sqlalchemy import text
|
||||
from database import engine
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def migrate():
|
||||
async with engine.begin() as conn:
|
||||
# Check if column already exists
|
||||
result = await conn.execute(text(
|
||||
"SELECT column_name FROM information_schema.columns "
|
||||
"WHERE table_name = 'recipe_steps' AND column_name = 'title'"
|
||||
))
|
||||
if result.scalar_one_or_none():
|
||||
logger.info("recipe_steps.title already exists, skipping")
|
||||
return
|
||||
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE recipe_steps ADD COLUMN IF NOT EXISTS title VARCHAR(255) DEFAULT NULL"
|
||||
))
|
||||
logger.info("Added recipe_steps.title column")
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
"""Add portions_needed_unit to recipe_sub_recipes table."""
|
||||
import logging
|
||||
from sqlalchemy import text
|
||||
from database import engine
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def migrate():
|
||||
async with engine.begin() as conn:
|
||||
result = await conn.execute(text(
|
||||
"SELECT column_name FROM information_schema.columns "
|
||||
"WHERE table_name = 'recipe_sub_recipes' AND column_name = 'portions_needed_unit'"
|
||||
))
|
||||
if result.scalar_one_or_none():
|
||||
logger.info("recipe_sub_recipes.portions_needed_unit already exists, skipping")
|
||||
return
|
||||
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE recipe_sub_recipes ADD COLUMN portions_needed_unit VARCHAR(10) DEFAULT NULL"
|
||||
))
|
||||
logger.info("Added portions_needed_unit column to recipe_sub_recipes")
|
||||
"""Add portions_needed_unit to recipe_sub_recipes table."""
|
||||
import logging
|
||||
from sqlalchemy import text
|
||||
from database import engine
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def migrate():
|
||||
async with engine.begin() as conn:
|
||||
result = await conn.execute(text(
|
||||
"SELECT column_name FROM information_schema.columns "
|
||||
"WHERE table_name = 'recipe_sub_recipes' AND column_name = 'portions_needed_unit'"
|
||||
))
|
||||
if result.scalar_one_or_none():
|
||||
logger.info("recipe_sub_recipes.portions_needed_unit already exists, skipping")
|
||||
return
|
||||
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE recipe_sub_recipes ADD COLUMN IF NOT EXISTS portions_needed_unit VARCHAR(10) DEFAULT NULL"
|
||||
))
|
||||
logger.info("Added portions_needed_unit column to recipe_sub_recipes")
|
||||
|
|
|
|||
|
|
@ -1,40 +1,40 @@
|
|||
"""
|
||||
Migration: Add order_email and account_number columns to suppliers table.
|
||||
Used for Purchase Order email sending and supplier identification.
|
||||
"""
|
||||
import asyncio
|
||||
from sqlalchemy import text
|
||||
from database import engine
|
||||
|
||||
|
||||
async def migrate():
|
||||
async with engine.begin() as conn:
|
||||
# Add order_email column
|
||||
try:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE suppliers ADD COLUMN order_email VARCHAR(255)"
|
||||
))
|
||||
print("+ Added order_email column to suppliers")
|
||||
except Exception as e:
|
||||
if "already exists" in str(e).lower() or "duplicate column" in str(e).lower():
|
||||
print("- order_email column already exists, skipping")
|
||||
else:
|
||||
raise
|
||||
|
||||
# Add account_number column
|
||||
try:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE suppliers ADD COLUMN account_number VARCHAR(100)"
|
||||
))
|
||||
print("+ Added account_number column to suppliers")
|
||||
except Exception as e:
|
||||
if "already exists" in str(e).lower() or "duplicate column" in str(e).lower():
|
||||
print("- account_number column already exists, skipping")
|
||||
else:
|
||||
raise
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Running migration: add_supplier_po_fields")
|
||||
asyncio.run(migrate())
|
||||
print("Migration complete!")
|
||||
"""
|
||||
Migration: Add order_email and account_number columns to suppliers table.
|
||||
Used for Purchase Order email sending and supplier identification.
|
||||
"""
|
||||
import asyncio
|
||||
from sqlalchemy import text
|
||||
from database import engine
|
||||
|
||||
|
||||
async def migrate():
|
||||
async with engine.begin() as conn:
|
||||
# Add order_email column
|
||||
try:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE suppliers ADD COLUMN IF NOT EXISTS order_email VARCHAR(255)"
|
||||
))
|
||||
print("+ Added order_email column to suppliers")
|
||||
except Exception as e:
|
||||
if "already exists" in str(e).lower() or "duplicate column" in str(e).lower():
|
||||
print("- order_email column already exists, skipping")
|
||||
else:
|
||||
raise
|
||||
|
||||
# Add account_number column
|
||||
try:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE suppliers ADD COLUMN IF NOT EXISTS account_number VARCHAR(100)"
|
||||
))
|
||||
print("+ Added account_number column to suppliers")
|
||||
except Exception as e:
|
||||
if "already exists" in str(e).lower() or "duplicate column" in str(e).lower():
|
||||
print("- account_number column already exists, skipping")
|
||||
else:
|
||||
raise
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Running migration: add_supplier_po_fields")
|
||||
asyncio.run(migrate())
|
||||
print("Migration complete!")
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ async def migrate():
|
|||
await conn.execute(text(
|
||||
"""
|
||||
ALTER TABLE suppliers
|
||||
ADD COLUMN skip_dext BOOLEAN NOT NULL DEFAULT FALSE
|
||||
ADD COLUMN IF NOT EXISTS skip_dext BOOLEAN NOT NULL DEFAULT FALSE
|
||||
"""
|
||||
))
|
||||
print("✓ Added skip_dext column to suppliers table")
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ async def run_migration():
|
|||
|
||||
# Add VAT rate columns to kitchen_settings table
|
||||
settings_columns = [
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN newbook_breakfast_vat_rate NUMERIC(5, 4) DEFAULT 0.10",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN newbook_dinner_vat_rate NUMERIC(5, 4) DEFAULT 0.10",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS newbook_breakfast_vat_rate NUMERIC(5, 4) DEFAULT 0.10",
|
||||
"ALTER TABLE kitchen_settings ADD COLUMN IF NOT EXISTS newbook_dinner_vat_rate NUMERIC(5, 4) DEFAULT 0.10",
|
||||
]
|
||||
|
||||
for sql in settings_columns:
|
||||
|
|
@ -36,8 +36,8 @@ async def run_migration():
|
|||
|
||||
# Add GL group columns to newbook_gl_accounts table (if not present)
|
||||
gl_columns = [
|
||||
"ALTER TABLE newbook_gl_accounts ADD COLUMN gl_group_id VARCHAR(50)",
|
||||
"ALTER TABLE newbook_gl_accounts ADD COLUMN gl_group_name VARCHAR(255)",
|
||||
"ALTER TABLE newbook_gl_accounts ADD COLUMN IF NOT EXISTS gl_group_id VARCHAR(50)",
|
||||
"ALTER TABLE newbook_gl_accounts ADD COLUMN IF NOT EXISTS gl_group_name VARCHAR(255)",
|
||||
]
|
||||
|
||||
for sql in gl_columns:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue