Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reusing SQLAlchemy models across projects

I have some standard SQLAlchemy models that I reuse across projects. Something like this:

from sqlalchemy import Column, Integer, String, Unicode
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Category(Base):
    __tablename__ = 'category'

    id = Column(Integer, primary_key=True)
    slug = Column(String(250), nullable=False, unique=True)
    title = Column(Unicode(250), nullable=False)

    def __call__(self):
        return self.title

I'd like to put this in a shared library and import it into each new project instead of cutting and pasting it, but I can't, because the declarative_base instance is defined separately in the project. If there's more than one, they won't share sessions. How do I work around this?

Here's another question that suggests using mixin classes. Could that work? Will SQLAlchemy accurately import foreign keys from mixin classes?

like image 702
Kiran Jonnalagadda Avatar asked Apr 27 '11 16:04

Kiran Jonnalagadda


1 Answers

When you call

Base = declarative_base()

SA create new metadata for this Base.

To reuse your models you must bind metadata of main models to reusable models, but before any import of your reusable models by:

Base.metadata = my_main_app.db.metadata

MixIn classes useful for repeating column declarations, and extending class methods. For connecting reusable apps based on MixIns you must define concrete class in code manualy for each model.

Will SQLAlchemy accurately import foreign keys from mixin classes?

MixIn class with foreign key and constraint

from sqlalchemy.schema import UniqueConstraint
from sqlalchemy.ext.declarative import declared_attr

class MessageMixIn(object):
    ttime = Column(DateTime)

    @declared_attr
    def sometable_id(cls):
        return Column(Integer, ForeignKey('sometable.id'))

    @declared_attr
    def __table_args__(cls):
        return (UniqueConstraint('sometable_id', 'ttime'), {})
like image 117
estin Avatar answered Nov 12 '22 19:11

estin