fix(db): avoid repeated sqlite schema initialization
This commit is contained in:
+23
-10
@@ -1,5 +1,6 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import threading
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from sqlalchemy import inspect, text
|
from sqlalchemy import inspect, text
|
||||||
@@ -10,6 +11,10 @@ from services.shared.schema_migrations import schema_management_mode, validate_s
|
|||||||
from services.shared.sql_models import Base
|
from services.shared.sql_models import Base
|
||||||
|
|
||||||
|
|
||||||
|
_SCHEMA_INIT_LOCK = threading.Lock()
|
||||||
|
_SCHEMA_INITIALIZED = False
|
||||||
|
|
||||||
|
|
||||||
def _table_columns(inspector, table_name: str) -> set[str]:
|
def _table_columns(inspector, table_name: str) -> set[str]:
|
||||||
return {item["name"] for item in inspector.get_columns(table_name)}
|
return {item["name"] for item in inspector.get_columns(table_name)}
|
||||||
|
|
||||||
@@ -588,15 +593,23 @@ def _apply_runtime_schema_compatibility() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def init_sql_schema() -> None:
|
def init_sql_schema() -> None:
|
||||||
if schema_management_mode() == "migrations":
|
global _SCHEMA_INITIALIZED
|
||||||
validate_schema_migrations_applied()
|
if _SCHEMA_INITIALIZED:
|
||||||
return
|
return
|
||||||
Base.metadata.create_all(bind=engine)
|
with _SCHEMA_INIT_LOCK:
|
||||||
for attempt in range(5):
|
if _SCHEMA_INITIALIZED:
|
||||||
try:
|
|
||||||
_apply_runtime_schema_compatibility()
|
|
||||||
return
|
return
|
||||||
except OperationalError as exc:
|
if schema_management_mode() == "migrations":
|
||||||
if "database is locked" not in str(exc).lower() or attempt >= 4:
|
validate_schema_migrations_applied()
|
||||||
raise
|
_SCHEMA_INITIALIZED = True
|
||||||
time.sleep(0.25 * (attempt + 1))
|
return
|
||||||
|
Base.metadata.create_all(bind=engine)
|
||||||
|
for attempt in range(5):
|
||||||
|
try:
|
||||||
|
_apply_runtime_schema_compatibility()
|
||||||
|
_SCHEMA_INITIALIZED = True
|
||||||
|
return
|
||||||
|
except OperationalError as exc:
|
||||||
|
if "database is locked" not in str(exc).lower() or attempt >= 4:
|
||||||
|
raise
|
||||||
|
time.sleep(0.25 * (attempt + 1))
|
||||||
|
|||||||
Reference in New Issue
Block a user