CSSer
CSSer

Reputation: 2587

Where should I put alembic's generated folder?

I'm starting a fastapi project, and using sqlalchemy + alembic to manage the sqlite db. Everything worked fine till alembic.

Here's the project folder structure:

app/
  - api/
  - core/
    - __init__.py
    - settings.py
  - db/
    - __init__.py
    - database.py

(I put a __init__.py in all folders)

At first, I tried to create migration folder inside db/, but with no success (same error as below). So I did alembic init migrations in root folder app/.

Now the folder looks like:

app/
  - api/
  - core/
    - __init__.py
    - settings.py
  - db/
    - __init__.py
    - database.py
  - migrations/
    - versions/
    - env.py
  - alembic.ini

And I modified the env.py:

from ..db.database import Base
from ..core.settings import settings

target_metadata = Base.metadata

def get_url():
    return settings.db_url

Then in app/, I tried

But all complained:

...
  from ..db.database import Base
ImportError: attempted relative import with no known parent package

And since we have prepend_sys_path = . in alembic.ini, so imports like from db.database import Base would work. However I used relative imports in db/database.py and core/settings.py and all other files too and don't want to modify the codes.

My questions are:

Upvotes: 4

Views: 3912

Answers (1)

ThePrince
ThePrince

Reputation: 890

Do not use relative imports.

First check, if your source files are in a folder called "src" or something similar, just try:

from src.db.database import Base
from src.core.settings import settings

Your venv is taking the parent folder of venv as the root of your project, NOT the migrations folder.

A second solution is to add these lines to the env.py file.

import sys
import os

project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "{NAME OF YOUR SOURCE ROOT FOLDER}"))
sys.path.insert(0, project_root)  # Insert at the beginning of the path

You must add this before you make any other imports, otherwise the error will be triggered before you get to this line.

Upvotes: 0

Related Questions