Fix database migration

This commit is contained in:
2025-10-05 22:44:19 +03:00
Unverified
parent e3e4c90d75
commit d046893165
4 changed files with 49 additions and 15 deletions
+17 -12
View File
@@ -1,25 +1,30 @@
from fastapi import FastAPI from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
import logging
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
from migration import run_migrations import subprocess
import sys
import os
from routes import account, messaging, profile, push from routes import account, messaging, profile, push
# Configure logging
logger = logging.getLogger("uvicorn.error")
logger.handlers.clear()
@asynccontextmanager @asynccontextmanager
async def lifespan(app: FastAPI): async def lifespan(app: FastAPI):
"""Handle application lifespan events.""" # Startup - run migration in separate process to avoid logging interference
# Startup
try: try:
logger.info("Starting database migration check...") print("Starting database migration check...")
run_migrations() # Run migration in a separate process
logger.info("Database migrations completed successfully.") subprocess.run(
[
sys.executable,
"-c",
"import sys; sys.path.append('.'); from migration import run_migrations; run_migrations()"
],
cwd=os.path.dirname(os.path.abspath(__file__))
# No capture_output - let it stream to terminal in real-time
# No text=True - let it use the terminal's encoding
)
except Exception as e: except Exception as e:
logger.error(f"Failed to run database migrations: {e}") print(f"Failed to run database migrations: {e}")
raise raise
yield yield
+31 -1
View File
@@ -9,8 +9,9 @@ from alembic.config import Config
from alembic.runtime.migration import MigrationContext from alembic.runtime.migration import MigrationContext
from sqlalchemy import create_engine from sqlalchemy import create_engine
from constants import DATABASE_URL from constants import DATABASE_URL
import logging
logger = logging.getLogger("uvicorn.error") logger = logging.getLogger(__name__)
def run_migrations(): def run_migrations():
""" """
@@ -25,6 +26,9 @@ def run_migrations():
# Create Alembic configuration # Create Alembic configuration
alembic_cfg = Config(os.path.join(current_dir, "alembic.ini")) alembic_cfg = Config(os.path.join(current_dir, "alembic.ini"))
# Disable Alembic's logging configuration to avoid interfering with FastAPI
alembic_cfg.set_main_option("configure_logging", "false")
# Set the database URL in the config # Set the database URL in the config
alembic_cfg.set_main_option("sqlalchemy.url", DATABASE_URL) alembic_cfg.set_main_option("sqlalchemy.url", DATABASE_URL)
@@ -71,6 +75,32 @@ def run_migrations():
# Create fresh migration # Create fresh migration
command.revision(alembic_cfg, autogenerate=True, message="Initial migration") command.revision(alembic_cfg, autogenerate=True, message="Initial migration")
logger.info("Initial migration created successfully.") logger.info("Initial migration created successfully.")
else:
# Migration files exist, check if we need to create a new migration for schema changes
logger.info("Migration files exist. Checking for pending schema changes...")
try:
# Create a new migration to detect any schema changes
command.revision(alembic_cfg, autogenerate=True, message="Auto-generated migration for schema changes")
# Check if the new migration is empty (no changes detected)
migration_files = [f for f in os.listdir(versions_dir) if f.endswith('.py') and not f.startswith('__')]
if migration_files:
latest_migration = max(migration_files)
migration_path = os.path.join(versions_dir, latest_migration)
# Check if migration is empty
with open(migration_path, 'r') as f:
content = f.read()
if 'pass' in content and 'op.create_table' not in content and 'op.add_column' not in content and 'op.drop_table' not in content and 'op.drop_column' not in content:
logger.info("No schema changes detected. Removing empty migration...")
# Remove the empty migration
os.remove(migration_path)
else:
logger.info("Schema changes detected. New migration created.")
except Exception as e:
logger.info(f"No new migrations needed or error creating migration: {e}")
pass
# Run the upgrade command # Run the upgrade command
logger.info("Running database migrations...") logger.info("Running database migrations...")
-1
View File
@@ -2,7 +2,6 @@ from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, Text, Boolean, DateTime, ForeignKey, inspect, null, text from sqlalchemy import Column, Integer, String, Text, Boolean, DateTime, ForeignKey, inspect, null, text
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from datetime import datetime from datetime import datetime
from db import engine
from pydantic import BaseModel from pydantic import BaseModel
Base = declarative_base() Base = declarative_base()
+1 -1
View File
@@ -8,7 +8,7 @@
"license": "GPL-3.0", "license": "GPL-3.0",
"authors": "denis0001-dev", "authors": "denis0001-dev",
"scripts": { "scripts": {
"backend:run": "cd backend && dotenv -e ../deployment/.env -- ../.venv/bin/fastapi dev --port 8300 main.py", "backend:run": "cd backend && dotenv -e ../deployment/.env -- ../.venv/bin/uvicorn main:app --host 127.0.0.1 --port 8300 --reload --reload-exclude './alembic' --reload-exclude './alembic/*' --reload-exclude './alembic/versions/*' --access-log",
"backend:dependencies": "python3 -m venv .venv && ./.venv/bin/pip3 install -r backend/requirements.txt", "backend:dependencies": "python3 -m venv .venv && ./.venv/bin/pip3 install -r backend/requirements.txt",
"backend:reinstall": "rm -rf .venv && npm run backend:dependencies", "backend:reinstall": "rm -rf .venv && npm run backend:dependencies",
"backend:clean": "rm -rf backend/data", "backend:clean": "rm -rf backend/data",