I am currently trying to create the following database schema with SQLAlchemy (using ext.declarative):
I have a base class MyBaseClassthat provides some common functions for all my public classes, a mixin class MetadataMixinthat provides the functionality for requesting metadata from imdb and saving. Each class that has subclasses MetadataMixinhas a field personsthat provides an M: N relation to class instances Personand a field persons_rolesthat provides a 1: N ratio to an object (one for each subclass) in which a roleparticular person is stored plays in an instance of the subclass.
This is an abridged version of what my code currently looks like:
from sqlalchemy import Column, Integer, Enum, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class MyBaseClass(object):
"""Base class for all publicly accessible classes"""
id = Column(Integer, primary_key=True)
class Person(MyBaseClass):
"""A Person"""
name = Column(Unicode)
movies = association_proxy('movie_roles', 'movie',
creator=lambda m: _PersonMovieRole(movie=m))
shows = association_proxy('show_roles', 'show',
creator=lambda s: _PersonShowRole(show=s=))
class _PersonMovieRole(Base):
"""Role for a Person in a Movie"""
__tablename__ = 'persons_movies'
id = Column(Integer, primary_key=True)
role = Column(Enum('none', 'actor', 'writer', 'director', 'producer'),
default='none')
person_id = Column(Integer, ForeignKey('persons.id'))
person = relationship('Person', backref='movie_roles')
movie_id = Column(Integer, ForeignKey('movies.id'))
movie = relationship('Movie', backref='persons_roles')
class _PersonShowRole(Base):
"""Role for a Person in a Show"""
__tablename__ = 'persons_shows'
id = Column(Integer, primary_key=True)
role = Column(Enum('none', 'actor', 'writer', 'director', 'producer'),
default='none')
person_id = Column(Integer, ForeignKey('persons.id'))
person = relationship('Person', backref='show_roles')
show_id = Column(Integer, ForeignKey('shows.id'))
show = relationship('Episode', backref='persons_roles')
class MetadataMixin(object):
"""Mixin class that provides metadata-fields and methods"""
persons = association_proxy('persons_roles', 'person',
creator=
class Movie(Base, MyBaseClass, MetadataMixin):
pass
What I'm trying to do is create a generic creatorfunction for association_proxythat creates a PersonMovieRole or PersonShowRole object, depending on the class of the particular instance to which it is added Person. At the moment, I'm stuck in the fact that I donβt know how to pass the calling class to the creator function. Is this possible, or maybe even an easier way for what I'm trying to accomplish?