diff --git a/alembic/env.py b/alembic/env.py index 8b10b6e..5b637c9 100644 --- a/alembic/env.py +++ b/alembic/env.py @@ -6,13 +6,25 @@ 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() +# Get the directory where this script is located +current_dir = Path(__file__).resolve().parent + +# Import our custom module for path setup +sys.path.insert(0, str(current_dir)) +try: + from find_modules import setup_python_path + # Setup Python path to find app modules in various environments + setup_python_path() +except ImportError: + # Fallback for direct path setup if the module can't be imported + project_root = current_dir.parent + 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(): + sys.path.insert(0, str(repo_path)) # this is the Alembic Config object, which provides # access to the values within the .ini file in use. @@ -32,7 +44,6 @@ 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: @@ -55,7 +66,26 @@ except ImportError: Base = getattr(db_module, "Base") break else: - raise ImportError("Could not find app modules in any path") + # Try to find modules in the container-specific location + model_path = Path('/app/repo/app/models/todo.py') + db_path = Path('/app/repo/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") + 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}") diff --git a/alembic/find_modules.py b/alembic/find_modules.py index 5a4445c..1ce7e3f 100644 --- a/alembic/find_modules.py +++ b/alembic/find_modules.py @@ -20,10 +20,54 @@ def setup_python_path(): 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)) + # Container environments often mount code in specific locations + # Check multiple possible locations + possible_repo_paths = [ + Path('/app/repo'), # Common Kubernetes/Docker path + Path('/app'), # Another common Docker path + Path('/projects/simpletodoapp-ayt143') # Local development path + ] + + # Add all existing paths to sys.path + for repo_path in possible_repo_paths: + if repo_path.exists() and str(repo_path) not in sys.path: + sys.path.insert(0, str(repo_path)) + + # Debug information to help troubleshoot path issues + print(f"Python sys.path configured as: {sys.path}") # Return the actual Python paths used, for debugging return sys.path + + +def find_module_path(module_name, possible_paths=None): + """ + Try to find a module by checking multiple possible locations. + Returns the full path to the module if found, None otherwise. + + Args: + module_name: Name of the module to find (e.g. 'app.models.todo') + possible_paths: List of base paths to check + + Returns: + Path object if module found, None otherwise + """ + if possible_paths is None: + possible_paths = sys.path + + module_parts = module_name.split('.') + + for base_path in possible_paths: + path = Path(base_path) + for part in module_parts: + path = path / part + + py_path = path.with_suffix('.py') + init_path = path / '__init__.py' + + if py_path.exists(): + return py_path + elif init_path.exists(): + return init_path + + return None diff --git a/test_migrations.py b/test_migrations.py new file mode 100644 index 0000000..e402bd6 --- /dev/null +++ b/test_migrations.py @@ -0,0 +1,55 @@ +""" +Test script to verify that Alembic migrations will work in the container environment. +""" +import os +import sys +from pathlib import Path + +print(f"Current working directory: {os.getcwd()}") +print(f"Initial Python path: {sys.path}") + +# Simulate the container environment where alembic is executed +repo_dir = Path('/app/repo') +if not repo_dir.exists(): + print(f"Simulating the /app/repo directory structure (not found on disk)") + # Just for testing, we'll use the current directory + repo_dir = Path(os.getcwd()) + +# Get paths for important files +alembic_dir = repo_dir / 'alembic' +env_py = alembic_dir / 'env.py' +find_modules_py = alembic_dir / 'find_modules.py' + +print(f"Alembic directory: {alembic_dir}") +print(f"env.py exists: {env_py.exists()}") +print(f"find_modules.py exists: {find_modules_py.exists()}") + +# Add alembic directory to Python path +if str(alembic_dir) not in sys.path: + sys.path.insert(0, str(alembic_dir)) + print(f"Added alembic directory to sys.path: {sys.path}") + +# Try to import our module +try: + from find_modules import setup_python_path + print(f"Successfully imported setup_python_path from find_modules") + + # Try to set up the Python path + paths = setup_python_path() + print(f"Updated Python path: {paths}") + + # Try to import our models + try: + from app.models import Todo + print(f"Successfully imported Todo model: {Todo}") + + from app.core.database import Base + print(f"Successfully imported Base from database module: {Base}") + + print("Migration imports should work correctly!") + except ImportError as e: + print(f"Error importing app modules: {e}") + print("You may need to run this script from the project root directory.") +except ImportError as e: + print(f"Error importing find_modules: {e}") + print("Make sure you're running this script from the project root directory.") \ No newline at end of file