mirror of
https://github.com/fromchat-messenger/web.git
synced 2026-09-22 19:15:08 +03:00
Fix database migration
This commit is contained in:
+17
-12
@@ -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
@@ -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...")
|
||||||
|
|||||||
@@ -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
@@ -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",
|
||||||
|
|||||||
Reference in New Issue
Block a user