В настоящее время я пытаюсь создать следующую схему базы данных с помощью 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
. На данный момент я застрял на том, что не знаю, как передать вызывающий класс в функцию создания.
Возможно ли это, или есть более простой способ для того, чего я пытаюсь достичь?