2

When declaring models in SQLAlchemy, you create a declarative_base class from which to inherit. I'm finding this somewhat problematic when wanting to declare models in multiple places and using them in yet another application (with relationships).

I'm approaching this from a Django background where it's common to have separate apps combined into one website. Each app declares its own models by inheriting from django.db.models.Model and you can create relationships to another model by simply importing its models and using it in the app.

Having models declared in various places is often useful. But this becomes a bit problematic due to SQLAlchemy's explicit MetaData or Base declarations. I'm not sure what's the best way to handle this is. My question is: What's the best way to declare SQLAlchemy models independently in order to later use them in combination?

I guess letting each models.py declare have its own declarative_base is a bad idea (SQLAlchemy docs say that all declarative models should inherit from the same base). Emulating Django's behavior would be to have a centrally declared declarative_base and simply import that everywhere. But that sort of makes each separate app tied to this central point (which is problematic when you want to create completely separate apps and you're not Django).

I'd rather have a central point pull in models and configure them, so that when a project wants to use e.g. my app's User model, it would import it and make it use the project's Base or MetaData or whatever is required. This might involve using "classical mappings" (but then you've got to pass around the same MetaData anyway).

EDIT: Well, I just saw a related question (Reusing SQLAlchemy models across projects) which sort of goes into the same territory. I'm not sure the accepted answer is the best solution (or if it even is one) though.

Using explicit columns instead of strings when specifying ForeignKey

Here's an attempt which seems to work:

app1.models:

Base = declarative_base()

class User(Base):
  id = Column(Integer, primary_key=True)
  name = Column(Text)

app2.models:

from app1.models import User

Base = declarative_base()

class Address(Base):
  user_id = Column(Integer, ForeignKey(User.id), primary_key=True)
  user = relationship(User, backref=backref('addresses'))
  street1 = Column(Text)
  ...

Hmm...

Community
  • 1
  • 1
vicvicvic
  • 6,025
  • 4
  • 38
  • 55
  • there's nothing "wrong" with having multiple Base classes, except the inconvenience. What's the downside of having all of your "models" ultimately be dependent on the concept of "your app", which has a single Base? unless you are truly looking to have each "model" as an independent, reusable library in its own source repository...? – zzzeek Mar 29 '13 at 14:23
  • Pretty much the case you're describing. I have one project focusing on developing a member/user data model and then various other projects working against that data model (and possibly each other). – vicvicvic Mar 29 '13 at 14:34

0 Answers0