Колба sqlalchemy многие-ко-многим вставить данные


Я пытаюсь сделать отношение"многие ко многим"здесь в Flask-SQLAlchemy, но, похоже, я не знаю, как заполнить " базу данных идентификаторов многих ко многим " . Не могли бы вы помочь мне понять, что я делаю неправильно и как это должно выглядеть?

class User(db.Model):
    __tablename__ = 'users'
    user_id = db.Column(db.Integer, primary_key=True)
    user_fistName = db.Column(db.String(64))
    user_lastName = db.Column(db.String(64))
    user_email = db.Column(db.String(128), unique=True)


class Class(db.Model):
    __tablename__ = 'classes'
    class_id = db.Column(db.Integer, primary_key=True)
    class_name = db.Column(db.String(128), unique=True)

И затем моя база данных идентификаторов:

student_identifier = db.Table('student_identifier',
    db.Column('class_id', db.Integer, db.ForeignKey('classes.class_id')),
    db.Column('user_id', db.Integer, db.ForeignKey('users.user_id'))
)

До сих пор это выглядит так, когда я пытаюсь вставить данные в базу данных.

# User
user1 = User(
            user_fistName='John',
            user_lastName='Doe',
            user_email='john@doe.es')

user2 = User(
            user_fistName='Jack',
            user_lastName='Doe',
            user_email='jack@doe.es')

user3 = User(
            user_fistName='Jane',
            user_lastName='Doe',
            user_email='jane@doe.es')

db.session.add_all([user1, user2, user3])
db.session.commit()

# Class
cl1 = Class(class_name='0A')
cl2 = Class(class_name='0B')
cl3 = Class(class_name='0C')
cl4 = Class(class_name='Math')
cl5 = Class(class_name='Spanish')
db.session.add_all([cl1, cl2, cl3, cl4, cl5])
db.session.commit()

Теперь моя проблема заключается в том, как добавить в базу данных "многие ко многим", поскольку я действительно не могу создать объект 'student_identifier'? Если бы я мог, это, возможно, выглядело бы так:

# Student Identifier
sti1  = StiClass(class_id=cl1.class_id, class_name=user1.user_id)
sti2  = StiClass(class_id=cl3.class_id, class_name=user1.user_id)
sti3  = StiClass(class_id=cl4.class_id, class_name=user1.user_id)
sti4  = StiClass(class_id=cl2.class_id, class_name=user2.user_id)
db.session.add_all([sti1, sti2, sti3, sti4])
db.session.commit()

Как я должен вставить в таблицу "многие ко многим" с ORM?

2 49

2 ответа:

Вам не нужно ничего добавлять непосредственно в таблицу ассоциаций, это сделает SQLAlchemy. Это более или менее из SQLAlchemy documentations:

association_table = db.Table('association', db.Model.metadata,
    db.Column('left_id', db.Integer, db.ForeignKey('left.id')),
    db.Column('right_id', db.Integer, db.ForeignKey('right.id'))
)

class Parent(db.Model):
    __tablename__ = 'left'
    id = db.Column(db.Integer, primary_key=True)
    children = db.relationship("Child",
                    secondary=association_table)

class Child(db.Model):
    __tablename__ = 'right'
    id = db.Column(db.Integer, primary_key=True)


p = Parent()
c = Child()
p.children.append(c)
db.session.add(p)
db.session.commit()

Поэтому ваш образец будет выглядеть следующим образом:

student_identifier = db.Table('student_identifier',
    db.Column('class_id', db.Integer, db.ForeignKey('classes.class_id')),
    db.Column('user_id', db.Integer, db.ForeignKey('students.user_id'))
)

class Student(db.Model):
    __tablename__ = 'students'
    user_id = db.Column(db.Integer, primary_key=True)
    user_fistName = db.Column(db.String(64))
    user_lastName = db.Column(db.String(64))
    user_email = db.Column(db.String(128), unique=True)


class Class(db.Model):
    __tablename__ = 'classes'
    class_id = db.Column(db.Integer, primary_key=True)
    class_name = db.Column(db.String(128), unique=True)
    students = db.relationship("Student",
                               secondary=student_identifier)

s = Student()
c = Class()
c.students.append(s)
db.session.add(c)
db.session.commit()

Во-первых, student_identifier определяется как таблица отражения SQLAlchemy, а не база данных.

Обычно, если вы правильно настроили все отношения между моделями и объектами таблицы отражения, вам нужно будет только иметь дело со связанными моделями (путем добавления объектов модели в список инструментов отношений), чтобы вставить данные в таблицы отражения, например, ответ @mehdi-sadeghi, приведенный выше.

Тем не менее, действительно есть способ вставлять непосредственно в таблицы отражения если вы не хотите устанавливать отношения. Например:

statement = student_identifier.insert().values(class_id=cl1.id, user_id=sti1.id)
db.session.execute(statement)
db.session.commit()

После этого вы должны увидеть, что строка отношения "многие ко многим" вставлена в таблицу отражения student_identifier. Не забудьте зафиксировать после выполнения каждой инструкции SQL, как это делается в транзакции.

Надеюсь, что это поможет вам с альтернативным подходом.