creating tables
This commit is contained in:
parent
b0055e174f
commit
1def6e3512
|
|
@ -25,7 +25,32 @@ if int(os.getenv("SANIC_MAINTENANCE", '0')) == 1:
|
||||||
while True:
|
while True:
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
from app.core.models import Memory
|
|
||||||
|
def init_db_schema_sync() -> None:
|
||||||
|
"""Initialise all SQLAlchemy models in the database before services start.
|
||||||
|
|
||||||
|
This ensures that every table defined on AlchemyBase.metadata (including
|
||||||
|
newer ones like DHT and service_config) exists before any component
|
||||||
|
accesses the database.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
from sqlalchemy import create_engine
|
||||||
|
from app.core.models import AlchemyBase # imports all models and populates metadata
|
||||||
|
|
||||||
|
db_url = os.environ.get('DATABASE_URL')
|
||||||
|
if not db_url:
|
||||||
|
raise RuntimeError('DATABASE_URL is not set')
|
||||||
|
|
||||||
|
# Normalise DSN to sync driver for schema creation
|
||||||
|
if '+asyncpg' in db_url:
|
||||||
|
db_url_sync = db_url.replace('+asyncpg', '+psycopg2')
|
||||||
|
else:
|
||||||
|
db_url_sync = db_url
|
||||||
|
|
||||||
|
sync_engine = create_engine(db_url_sync, pool_pre_ping=True)
|
||||||
|
AlchemyBase.metadata.create_all(sync_engine)
|
||||||
|
except Exception as e:
|
||||||
|
make_log('Startup', f'DB sync init failed: {e}', level='error')
|
||||||
|
|
||||||
|
|
||||||
async def queue_daemon(app):
|
async def queue_daemon(app):
|
||||||
|
|
@ -78,27 +103,15 @@ async def execute_queue(app):
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
# Ensure DB schema is fully initialised for all models
|
||||||
|
init_db_schema_sync()
|
||||||
|
|
||||||
|
from app.core.models import Memory
|
||||||
main_memory = Memory()
|
main_memory = Memory()
|
||||||
if startup_target == '__main__':
|
if startup_target == '__main__':
|
||||||
# Defer heavy imports to avoid side effects in background services
|
# Defer heavy imports to avoid side effects in background services
|
||||||
# Mark this process as the primary node for seeding/config init
|
# Mark this process as the primary node for seeding/config init
|
||||||
os.environ.setdefault('NODE_ROLE', 'primary')
|
os.environ.setdefault('NODE_ROLE', 'primary')
|
||||||
# Create DB tables synchronously before importing HTTP app to satisfy _secrets
|
|
||||||
try:
|
|
||||||
from sqlalchemy import create_engine
|
|
||||||
from app.core.models import AlchemyBase # imports all models
|
|
||||||
db_url = os.environ.get('DATABASE_URL')
|
|
||||||
if not db_url:
|
|
||||||
raise RuntimeError('DATABASE_URL is not set')
|
|
||||||
# Normalize to sync driver
|
|
||||||
if '+asyncpg' in db_url:
|
|
||||||
db_url_sync = db_url.replace('+asyncpg', '+psycopg2')
|
|
||||||
else:
|
|
||||||
db_url_sync = db_url
|
|
||||||
sync_engine = create_engine(db_url_sync, pool_pre_ping=True)
|
|
||||||
AlchemyBase.metadata.create_all(sync_engine)
|
|
||||||
except Exception as e:
|
|
||||||
make_log('Startup', f'DB sync init failed: {e}', level='error')
|
|
||||||
from app.api import app
|
from app.api import app
|
||||||
# Delay aiogram dispatcher creation until loop is running
|
# Delay aiogram dispatcher creation until loop is running
|
||||||
from app.core._config import SANIC_PORT, PROJECT_HOST, DATABASE_URL
|
from app.core._config import SANIC_PORT, PROJECT_HOST, DATABASE_URL
|
||||||
|
|
|
||||||
|
|
@ -32,22 +32,6 @@ def _init_seed_via_db() -> bytes:
|
||||||
engine = create_engine(DATABASE_URL, pool_pre_ping=True)
|
engine = create_engine(DATABASE_URL, pool_pre_ping=True)
|
||||||
role = os.getenv("NODE_ROLE", "worker").lower()
|
role = os.getenv("NODE_ROLE", "worker").lower()
|
||||||
|
|
||||||
# Best-effort: ensure service_config table exists before waiting on it.
|
|
||||||
# This complements the synchronous init in app.__main__ and protects
|
|
||||||
# against ordering issues where _secrets is imported before that init runs.
|
|
||||||
try:
|
|
||||||
from sqlalchemy.exc import SQLAlchemyError
|
|
||||||
|
|
||||||
with engine.begin() as conn:
|
|
||||||
inspector = inspect(conn)
|
|
||||||
if not inspector.has_table('service_config'):
|
|
||||||
ServiceConfigValue.__table__.create(bind=conn, checkfirst=True)
|
|
||||||
except SQLAlchemyError as exc:
|
|
||||||
make_log("HotWallet", f"Failed to ensure service_config table: {exc}", level="error")
|
|
||||||
except Exception:
|
|
||||||
# Avoid failing hard here; the fallback waiter below may still succeed
|
|
||||||
pass
|
|
||||||
|
|
||||||
def db_ready(conn) -> bool:
|
def db_ready(conn) -> bool:
|
||||||
try:
|
try:
|
||||||
inspector = inspect(conn)
|
inspector = inspect(conn)
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ class DHTStore:
|
||||||
try:
|
try:
|
||||||
from sqlalchemy import create_engine
|
from sqlalchemy import create_engine
|
||||||
from sqlalchemy.orm import sessionmaker
|
from sqlalchemy.orm import sessionmaker
|
||||||
|
|
||||||
from app.core._config import DATABASE_URL
|
from app.core._config import DATABASE_URL
|
||||||
from app.core.models.dht import DHTRecordRow
|
from app.core.models.dht import DHTRecordRow
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue