Как правильно описать ассоциативный объект с помощью SQLalchemy декларативным способом? - PullRequest
2 голосов
/ 28 февраля 2010

Я ищу способ описать ассоциативный объект декларативным способом. Помимо хранения внешних ключей в таблице сопоставлений, мне нужно хранить информацию, такую ​​как дата создания сопоставления.

Сегодня моя модель выглядит так:

# Define the User class
class User(Base):
    __tablename__ = 'users'

    # Define User fields
    id = schema.Column(types.Integer(unsigned=True),
        schema.Sequence('users_seq_id', optional=True), primary_key=True)
    password = schema.Column(types.Unicode(64), nullable=False)

# Define the UserSubset class
class UserSubset(Base):
    __tablename__ = 'subsets'

    # Define UserSubset fields
    id = schema.Column(types.Integer(unsigned=True),
        schema.Sequence('subsets_seq_id', optional=True), primary_key=True)
    some_short_description = schema.Column(types.Unicode(50), nullable=False)

# Define the subset memberships table
subset_memberships = schema.Table('group_memberships', Base.metadata,
    schema.Column('user_id', types.Integer(unsigned=True), ForeignKey('users.id')),
    schema.Column('subset_id', types.Integer(unsigned=True), ForeignKey('subsets.id')),
    schema.Column('created', types.DateTime(), default=now, nullable=False),
)

Могу ли я соединить все в ассоциативный объект? Или я должен изменить прекратить использовать декларативный способ?

Ответы [ 2 ]

1 голос
/ 28 февраля 2010

То, что вы используете в данный момент, это просто отношение «многие ко многим». Как работать с объектами ассоциации описано в документах .

Существует также расширение под названием associationproxy , которое упрощает соотношение.

0 голосов
/ 28 февраля 2010

Как вы можете видеть в руководстве , настройка отношения один ко многим действительно проста:

class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    addresses = relation("Address", backref="user")

class Address(Base):
    __tablename__ = 'addresses'

    id = Column(Integer, primary_key=True)
    email = Column(String(50))
    user_id = Column(Integer, ForeignKey('users.id'))

Отношения ко многим не намного сложнее:

Нет ничего особенного во многих для многих с декларативным. Вторичный аргумент дляlation () по-прежнему требует объект Table, а не декларативный класс. Таблица должна совместно использовать тот же объект MetaData, который используется декларативной базой:

 keywords = Table('keywords', Base.metadata,
                     Column('author_id', Integer, ForeignKey('authors.id')),
                     Column('keyword_id', Integer, ForeignKey('keywords.id'))
             )

 class Author(Base):
     __tablename__ = 'authors'
     id = Column(Integer, primary_key=True)
     keywords = relation("Keyword", secondary=keywords)

Обычно вы должны не отображать класс, а также указывать его таблицу в отношении "многие ко многим", поскольку ORM может выдавать дубликаты операторов INSERT и DELETE.

В любом случае, то, что вы, кажется, делаете, может быть лучше подано с наследованием . Конечно, могут быть сложные табличные отношения, которые будут патологическим случаем для декларативного способа, но, похоже, это не один из них.

Еще одна вещь, комментарии к коду должны указывать, что делает следующий код и почему, а не как он это делает. Наличие комментария # Define the User class почти похоже на строку кода с текстом a = 1 # assing value 1 to variable "a".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...