Ошибка сеанса SQLAlchemy при создании объекта с отношением m2m - PullRequest
0 голосов
/ 23 апреля 2020

Я новичок в SQLAlchemy и Flask. Я пытаюсь создать объект ( book ) с отношением m2m и добавить существующий объект ( tag_2 ) к отношению:

book = Book(title='title')

tag_1 = Tag(name='tag')
book.tags.append(tag_1)     # New tag works well

tag_2 = Tag.query.get(123)  # Get existed tag by id
print(tag_2)                # >>> Tag #123
book.tags.append(tag_2)     # ERROR: Object '<Tag at ...>' is already attached to session '1'

self.session.add(book)
self.session.commit()

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

Мои модели:

book_tags = db.Table('book_tags', db.metadata,
    db.Column('tag_id', db.Integer, db.ForeignKey('tag.id')),
    db.Column('book_id', db.Integer, db.ForeignKey('book.id'))
)


class Tag(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), unique=True)


class Book(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(300), nullable=False)
    tags = db.relationship('Tag', secondary=book_tags)

Я использую sqlite в качестве БД.

Ответы [ 2 ]

1 голос
/ 23 апреля 2020

Кажется, вы используете разные self.session для получения Tag, а для получения Book вы затем пытаетесь добавить Tag к. Чтобы иметь возможность добавлять объект A к объекту B , они оба должны существовать в одном сеансе.

Трудно сказать, как вы создаете сеанс, потому что в вашем посте только код, который работает с ним, но убедитесь, что у вас только один сеанс.

0 голосов
/ 23 апреля 2020
tags = db.relationship(
    'Tag',
    secondary=book_tags,
    backref=db.backref('book', lazy='dynamic')
)

Вам необходимо добавить backref в отношении m2m, потому что
Использование backref просто автоматизирует создание свойства отношения на другом конце. backref = 'book' - это что-то вроде того, что book = db.relationship ('book') явно указана в классе Tag (+ back население). Используя объект backref (), вы можете передать аргументы этому отношению.

...