sqlalchemy/alembic · error · ImportError

Can't find Python file

Error message

Can't find Python file %s

What it means

Raised as ImportError by load_python_file when the requested .py file does not exist on disk and no compiled .pyc/.pyo fallback can be found (pyfiles.py:112-118). load_python_file is used to dynamically load env.py, custom env.py modules, and migration scripts. The function first checks for the .py file, then tries pyc_file_from_path for a bytecode fallback; if both fail, the ImportError is raised.

Solutions

  1. Verify the script_location path in alembic.ini/pyproject.toml points to the correct existing directory.
  2. Check that env.py exists: ls <script_location>/env.py.
  3. If the migrations directory was never created, run alembic init <directory> to scaffold it.
  4. Ensure you're running alembic from the correct working directory, or use absolute paths in the config.
  5. Check file permissions and case sensitivity (env.py, not Env.py or ENV.PY).

Example fix

# before: alembic.ini
[alembic]
script_location = ./migrations  # directory doesn't exist

# after
[alembic]
script_location = ./alembic   # correct directory with env.py

# or scaffold the directory
alembic init alembic
Defensive patterns

Strategy: validation

Validate before calling

import os

def python_file_exists(directory, filename):
    path = os.path.join(directory, filename)
    if os.path.exists(path):
        return True
    # check for .pyc fallback
    base, _ = os.path.splitext(path)
    import importlib.machinery
    for ext in importlib.machinery.BYTECODE_SUFFIXES:
        if os.path.exists(base + ext):
            return True
    return False

Try / catch

try:
    module = load_python_file(dir_, filename)
except ImportError as e:
    if "Can't find Python file" in str(e):
        print(f"File not found: {os.path.join(dir_, filename)}")
        print("Check script_location in your config and ensure env.py exists.")
    raise

Prevention

When it happens

Trigger: Calling load_python_file(dir_, filename) where dir_/filename doesn't exist and no .pyc sibling exists. Happens when Alembic's config points to a nonexistent env.py or when the script_location directory is wrong. Also triggered by 'alembic edit' or migration execution when the script file was deleted.

Common situations: Incorrect script_location in alembic.ini pointing to a non-existent migrations directory. env.py was accidentally deleted or never created (e.g., interrupted 'alembic init'). Running from the wrong working directory so relative paths don't resolve. Filesystem case sensitivity issues on Linux (Env.py vs env.py).

Related errors


AI-assisted analysis of sqlalchemy/alembic@5551b5d35f (2026-08-11). Data as JSON: /api/errors/f39bc862f9da397e. Report an issue: GitHub.

Appendix: source

Thrown at alembic/util/pyfiles.py:118

def load_python_file(
    dir_: str | os.PathLike[str], filename: str | os.PathLike[str]
) -> ModuleType:
    """Load a file from the given path as a Python module."""

    dir_ = pathlib.Path(dir_)
    filename_as_path = pathlib.Path(filename)
    filename = filename_as_path.name

    module_id = re.sub(r"\W", "_", filename)
    path = dir_ / filename
    ext = path.suffix
    if ext == ".py":
        if path.exists():
            module = load_module_py(module_id, path)
        else:
            pyc_path = pyc_file_from_path(path)
            if pyc_path is None:
                raise ImportError("Can't find Python file %s" % path)
            else:
                module = load_module_py(module_id, pyc_path)
    elif ext in (".pyc", ".pyo"):
        module = load_module_py(module_id, path)
    else:
        assert False
    return module


def load_module_py(module_id: str, path: str | os.PathLike[str]) -> ModuleType:
    spec = importlib.util.spec_from_file_location(module_id, path)
    assert spec
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)  # type: ignore
    return module


def _preserving_path_as_str(path: str | os.PathLike[str]) -> str:

View on GitHub (pinned to 5551b5d35f)