Fix Alembic migration import error in containerized environment

This commit is contained in:
Automated Action 2025-05-19 01:03:25 +00:00
parent da0fe5a40e
commit a1c3bee298
3 changed files with 124 additions and 4 deletions

View File

@ -1,11 +1,19 @@
"""
Alembic environment script for database migrations
"""
import sys
from logging.config import fileConfig
from pathlib import Path
from alembic import context
# Custom module to help with finding modules in containerized environments
from alembic.find_modules import setup_python_path
from sqlalchemy import engine_from_config, pool
# Setup Python path to find app modules in various environments
setup_python_path()
# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config
@ -15,10 +23,43 @@ config = context.config
if config.config_file_name is not None:
fileConfig(config.config_file_name)
# add your model's MetaData object here
# for 'autogenerate' support
from app.models import Todo # noqa
from app.core.database import Base # noqa
# Try different import strategies to handle various deployment environments
try:
# Standard import approach
from app.models import Todo # noqa
from app.core.database import Base # noqa
except ImportError:
try:
# Path-based import for some container setups
import importlib.util
import sys
# Try to find the module file
for base_path in sys.path:
model_path = Path(base_path) / "app" / "models" / "todo.py"
db_path = Path(base_path) / "app" / "core" / "database.py"
if model_path.exists() and db_path.exists():
# Load the todo module
spec = importlib.util.spec_from_file_location("todo", model_path)
todo_module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(todo_module)
# Load the database module
spec = importlib.util.spec_from_file_location("database", db_path)
db_module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(db_module)
# Get the required objects
Todo = getattr(todo_module, "Todo")
Base = getattr(db_module, "Base")
break
else:
raise ImportError("Could not find app modules in any path")
except Exception as e:
print(f"Error importing models: {e}")
print(f"Current sys.path: {sys.path}")
raise
target_metadata = Base.metadata

29
alembic/find_modules.py Normal file
View File

@ -0,0 +1,29 @@
"""
Module finder helper for Alembic migrations in containerized environments.
"""
import sys
from pathlib import Path
def setup_python_path():
"""
Add necessary paths to Python's sys.path to make imports work
in various environments including Docker containers
"""
# Get the directory where this script is located
current_dir = Path(__file__).resolve().parent
# The project root is one level up from the 'alembic' directory
project_root = current_dir.parent
# Add the project root to the Python path if it's not already there
if str(project_root) not in sys.path:
sys.path.insert(0, str(project_root))
# Check if we're in a Docker container with code mounted at /app/repo
repo_path = Path('/app/repo')
if repo_path.exists() and str(repo_path) not in sys.path:
sys.path.insert(0, str(repo_path))
# Return the actual Python paths used, for debugging
return sys.path

50
test_imports.py Normal file
View File

@ -0,0 +1,50 @@
"""
Test script to verify imports work correctly.
This can be run both locally and in the container to verify the setup.
"""
import os
import sys
# Print current working directory
print(f"Current working directory: {os.getcwd()}")
# Print Python path
print(f"Python path: {sys.path}")
# Try to import the app modules
try:
# Add current directory to path
sys.path.insert(0, os.getcwd())
# Try importing the models
from app.models import Todo
print(f"Successfully imported Todo from app.models: {Todo}")
from app.core.database import Base
print(f"Successfully imported Base from app.core.database: {Base}")
print("All imports succeeded!")
except Exception as e:
print(f"Error importing modules: {e}")
# Try a different approach for containerized environments
try:
# Try to execute the find_modules code
sys.path.insert(0, os.path.join(os.getcwd(), 'alembic'))
from find_modules import setup_python_path
# Setup paths
paths = setup_python_path()
print(f"Updated paths: {paths}")
# Try importing again
from app.models import Todo
print(f"Successfully imported Todo after path setup: {Todo}")
from app.core.database import Base
print(f"Successfully imported Base after path setup: {Base}")
print("Imports succeeded after path setup!")
except Exception as inner_e:
print(f"Still failed after path setup: {inner_e}")
print("This might indicate a deeper issue with the module structure.")