Python sqlalchemy多对多插入数据

Python sqlalchemy多对多插入数据,python,flask,sqlalchemy,flask-sqlalchemy,Python,Flask,Sqlalchemy,Flask Sqlalchemy,我试图在Alchemy中建立多对多关系,但似乎我不知道如何填充“多对多标识符数据库”。你能不能帮我理解我做错了什么,以及应该是什么样子 类用户(db.Model): __tablename_uu='users' user\u id=db.Column(db.Integer,主键=True) user_fistName=db.Column(db.String(64)) user_lastName=db.Column(db.String(64)) user_email=db.Column(db.St

我试图在Alchemy中建立多对多关系,但似乎我不知道如何填充“多对多标识符数据库”。你能不能帮我理解我做错了什么,以及应该是什么样子

类用户(db.Model):
__tablename_uu='users'
user\u id=db.Column(db.Integer,主键=True)
user_fistName=db.Column(db.String(64))
user_lastName=db.Column(db.String(64))
user_email=db.Column(db.String(128),unique=True)
类别(db.Model):
__tablename_uu='classes'
class\u id=db.Column(db.Integer,主键=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()
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()

如何使用ORM插入到多对多表中?

您不需要直接向关联表添加任何内容,SQLAlchemy可以做到这一点。这或多或少来自:

因此,您的样本如下:

# 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()
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\u标识符
被定义为SQLAlchemy反射表,而不是数据库

通常,如果您在模型和反射表对象之间正确设置了所有关系,则只需处理相关模型(通过将模型对象添加到关系工具列表中)即可将数据插入反射表,例如,上面提供的答案@mehdi sadeghi

但是,如果不想设置关系,确实有一种方法可以直接插入到反射表中。例如:

statement = student_identifier.insert().values(class_id=cl1.id, user_id=sti1.id)
db.session.execute(statement)
db.session.commit()
之后,您应该能够看到一个多对多关系行被插入到
student\u标识符
reflection表中。不要忘记在事务中执行每个SQL语句后提交


希望这能帮助您找到另一种方法。

要扩展考吉尔的答案,您还可以使用
extend
一次添加多个条目:

class_ = db.session.query(Class).first()
new_students = db.session.query(Student).all()
class_.students.extend(new_students)
db.session.add(class_)
db.session.commit()

如何导入此反射表或关联表?@jibinmathew就像导入类和其他符号一样。@jibinmathew导入关联表时我也有问题,所以我在本地导入表,正是在上面我调用它的地方。@GofyandKitty这可能是代码库中循环依赖项/导入的指示器,因此您需要使用本地导入(提供名称空间)才能使其工作。非常感谢您共享此解决方案。你真的救了meLet说我的学生已经在桌子上了。我如何将它们附加到类中,而不必每次都查询每个学生的全部数据(仅使用foreing键)?@axwell,如果您经常要求学生上课(即检查更新时),您可以使用lazy='subquery'调整关系,如下所示:
students=db.relationship(“学生”),secondary=student\u identifier,lazy='subquery',backref=db.backref('classes',lazy=True))
@axwell如果学生已经存在,也可以这样插入:
session.execute(student_identifier.insert(),params={“class_id”:class_id,“user_id”:user_id},)