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

#python #orm #sqlalchemy #pyramid

#python #orm #sqlalchemy #пирамида

Вопрос:

Я создал отношения «многие ко многим» с sqlalchemy следующим образом:

 subject_books = Table('subject_books', Base.metadata,
    Column('subject_id', Integer, ForeignKey('subjects.id')),
    Column('book_id', Integer, ForeignKey('books.id')),
    Column('group', Integer)
)

class Subject(Base):
    __tablename__ = 'subjects'
    id = Column(Integer, primary_key=True)
    value = Column(Unicode(255), unique=True)

class Book(Base):
    __tablename__ = 'books'
    id =  Column(Integer, primary_key=True)
    title = Column(Unicode(255))
    isbn = Column(Unicode(24))
    subjects = relationship('Subject', secondary=subject_books, collection_class=attribute_mapped_collection('group'), backref='books')
  

после этого я создал тест, подобный следующему:

 book = Book(title='first book',isbn='test')
book.subjects[0] = Subject(value='first subject')
book.subjects[1] = Subject(value='second subject')

session.add(book)
transaction.commit()
  

и это работает нормально. Но чего я действительно хочу, так это хранить более одного объекта с одинаковым значением группы, поэтому я попробовал следующий тест:

 book = Book(title='first book',isbn='test')
book.subjects[0] = [Subject(value='first subject'),Subject(value='second subject')]
book.subjects[1] = [Subject(value='third subject'),Subject(value='forth subject')]

session.add(book)
transaction.commit()
  

но это не работает.

Можно ли это сделать с помощью sqlalchemy?

Заранее спасибо

Комментарии:

1. Я думаю, что модель, которая у вас есть, хорошо представлена на уровне БД. Но простой способ работать с тем, с чем вы хотите… Я не уверен в готовом решении, но вы можете попытаться реализовать свою собственную пользовательскую коллекцию (см. sqlalchemy.org/docs/orm /… )

Ответ №1:

Рази

Я думаю, вы строите неправильные отношения.

Ваше отношение должно быть

закажите тему M2M

тема M2M group

Итак, вам нужно создать еще одну модель для group, и она должна быть назначена как m2m в теме

Ваши модели будут похожи.

 subject_books = Table('subject_books', Base.metadata,
    Column('subject_id', Integer, ForeignKey('subjects.id')),
    Column('book_id', Integer, ForeignKey('books.id')),        
)
subject_group = Table('subject_groups', Base.metadata,
    Column('group_id', Integer, ForeignKey('groups.id')),
    Column('subject_id', Integer, ForeignKey('subjects.id')),
)

class Subject(Base):
    __tablename__ = 'subjects'
    id = Column(Integer, primary_key=True)
    value = Column(Unicode(255), unique=True)
    groups = relationship('Groups', secondary=subject_groups, backref='subjects')

class Groups(Base):
    __tablename__ = 'groups'
    id = Column(Integer, primary_key=True)
    name = Column(Unicode(255), unique=True)

class Book(Base):
    __tablename__ = 'books'
    id =  Column(Integer, primary_key=True)
    title = Column(Unicode(255))
    isbn = Column(Unicode(24))
    subjects = relationship('Subject', secondary=subject_books, backref='books')
  

Я также проверяю документы на наличие attribute_mapped_collection. Но каждый раз я обнаруживал, что каждый ключ связан только с одним объектом, не более одного. Если вы где-нибудь читаете, пожалуйста, предоставьте ссылку, чтобы я мог проверить, как она будет вписываться в ваш код.

Я думаю, это вам поможет.