SQLAlchemy: множественное наследование с динамической функцией создателя 'association_proxy'

В настоящее время я пытаюсь создать следующую схему базы данных с помощью SQLAlchemy (используя ext.declarative):

У меня есть базовый класс MyBaseClass, который обеспечивает некоторую общую функциональность для всех моих общедоступных классов, класс mixin MetadataMixin, который обеспечивает функциональность для запроса метаданных из imdb и их хранения. Каждый класс, который является подклассом MetadataMixin, имеет поле persons, которое обеспечивает связь M:N с экземплярами класса Person, и поле persons_roles, которое обеспечивает связь 1:N с объектом (по одному для каждого подкласса), который хранит роль, которую играет конкретный Person в экземпляре подкласса.

Вот сокращенная версия того, как выглядит мой код на данный момент:

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

Я пытаюсь создать общую функцию creator для association_proxy, которая создает либо объект PersonMovieRole, либо PersonShowRole, в зависимости от класса конкретного экземпляра, к которому добавляется Person. На данный момент я застрял на том, что не знаю, как передать вызывающий класс в функцию создания. Возможно ли это, или есть более простой способ для того, чего я пытаюсь достичь?

5
задан jbaiter 23 April 2011 в 20:29
поделиться