简体   繁体   中英

Is it possible to use SQLAlchemy where the models are defined in different files?

I'm using SQLAlchemy for the first time and trying to define my models / schema. My only experience with ORM prior to this was with Rails and ActiveRecord .

Anyway, following SQLAlchemy's ORM Quick Start, this is the basic example they use (I have removed a few lines which are not relevant to my question):

from sqlalchemy import ForeignKey
from sqlalchemy import String
from sqlalchemy.orm import DeclarativeBase
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import relationship

class Base(DeclarativeBase):
    pass

class User(Base):
    __tablename__ = "user_account"

    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str] = mapped_column(String(30))

    addresses: Mapped[list["Address"]] = relationship(
        back_populates="user", cascade="all, delete-orphan"
    )

class Address(Base):
    __tablename__ = "address"

    id: Mapped[int] = mapped_column(primary_key=True)
    email_address: Mapped[str]
    user_id: Mapped[int] = mapped_column(ForeignKey("user_account.id"))

    user: Mapped["User"] = relationship(back_populates="addresses")

My question is: is it possible to create two models in separate files ( user.py and address.py ), defining each model in its own file, and then import them and run a command like the following in order to instantiate the database:

from sqlalchemy import create_engine
engine = create_engine("sqlite://", echo=True)
Base.metadata.create_all(engine)

Yes -- what you are asking is both possible and is the standard way of creating SQLAlchemy Schemas.

The only gotcha is that you want all of your models to inherit from the same DeclarativeBase . This is essentially what registers them with SQLAlchemy and other plugins/tools like Alembic.

There are a few organization structures you can use, but a simple and common one is something like this:

- project_root
  - models
    + __init__.py
    + user.py
    + address.py
  - utils
  - scripts

In models.__init__ , create and export your Base (I'd recommend giving it a slightly more specific name, such as ModelBase ). Then in each of your model files, just import ModelBase and cut/paste your existing code.

Some projects enforce a single model per file. Others group related models together.

Since all of your models import and use a single DeclaritiveBase , you can call methods like BaseModel.metadata.create_all() . Just keep in mind you will still need to import those actual models somewhere.

An easy way to handle that is to import them inside of models.__init__.py . That way you will essentially load them whenever you import and use ModelBase .

# models.__init__.py
from .user import User
from .address import Address

class ModelBase(DeclarativeBase):
    pass

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM