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
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue