Fix UNIQUE constraint error in get_or_create_user_account
Handles race condition where user account already exists from initial sync but without user_id set. When user configures wallet, code now: - Catches IntegrityError on UNIQUE constraint for accounts.name - Fetches existing account by name - Updates user_id if NULL or different - Returns existing account instead of failing This fixes the error that occurred when users configured their wallet after their accounts were created during the initial Beancount sync. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
a71d9b7fa5
commit
72e8fe8ee4
1 changed files with 46 additions and 7 deletions
39
crud.py
39
crud.py
|
|
@ -283,6 +283,7 @@ async def get_or_create_user_account(
|
||||||
logger.error(f"[CASTLE DB] Account still not found after sync: {account_name}")
|
logger.error(f"[CASTLE DB] Account still not found after sync: {account_name}")
|
||||||
# Fallback: create directly in Castle DB if sync failed
|
# Fallback: create directly in Castle DB if sync failed
|
||||||
logger.info(f"[CASTLE DB] Creating account directly in Castle DB: {account_name}")
|
logger.info(f"[CASTLE DB] Creating account directly in Castle DB: {account_name}")
|
||||||
|
try:
|
||||||
account = await create_account(
|
account = await create_account(
|
||||||
CreateAccount(
|
CreateAccount(
|
||||||
name=account_name,
|
name=account_name,
|
||||||
|
|
@ -291,6 +292,44 @@ async def get_or_create_user_account(
|
||||||
user_id=user_id,
|
user_id=user_id,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
except Exception as e:
|
||||||
|
# Handle UNIQUE constraint error - account already exists
|
||||||
|
if "UNIQUE constraint failed" in str(e) and "accounts.name" in str(e):
|
||||||
|
logger.warning(f"[CASTLE DB] Account already exists (UNIQUE constraint), fetching by name: {account_name}")
|
||||||
|
# Fetch existing account by name only (ignore user_id in query)
|
||||||
|
account = await db.fetchone(
|
||||||
|
"""
|
||||||
|
SELECT * FROM accounts
|
||||||
|
WHERE name = :name
|
||||||
|
""",
|
||||||
|
{"name": account_name},
|
||||||
|
Account,
|
||||||
|
)
|
||||||
|
if account:
|
||||||
|
logger.info(f"[CASTLE DB] Found existing account: {account_name} (user_id: {account.user_id})")
|
||||||
|
# Update user_id if it's NULL or different
|
||||||
|
if account.user_id != user_id:
|
||||||
|
logger.info(f"[CASTLE DB] Updating account user_id from {account.user_id} to {user_id}")
|
||||||
|
await db.execute(
|
||||||
|
"""
|
||||||
|
UPDATE accounts
|
||||||
|
SET user_id = :user_id
|
||||||
|
WHERE name = :name
|
||||||
|
""",
|
||||||
|
{"user_id": user_id, "name": account_name}
|
||||||
|
)
|
||||||
|
# Refresh account from DB
|
||||||
|
account = await db.fetchone(
|
||||||
|
"""
|
||||||
|
SELECT * FROM accounts
|
||||||
|
WHERE name = :name
|
||||||
|
""",
|
||||||
|
{"name": account_name},
|
||||||
|
Account,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# Re-raise if it's a different error
|
||||||
|
raise
|
||||||
else:
|
else:
|
||||||
logger.info(f"[CASTLE DB] Account already exists in Castle DB: {account_name}")
|
logger.info(f"[CASTLE DB] Account already exists in Castle DB: {account_name}")
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue