2014-09-04 174 views
37

我想在這裏做一個多對多的關係在這裏燒瓶SQLAlchemy,但似乎我不知道如何填寫「多對多標識符數據庫「。你能幫我理解我做錯了什麼以及它應該如何看待?燒瓶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='[email protected]') 

user2 = User(
      user_fistName='Jack', 
      user_lastName='Doe', 
      user_email='[email protected]') 

user3 = User(
      user_fistName='Jane', 
      user_lastName='Doe', 
      user_email='[email protected]') 

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的多表到多表?

回答

62

你不需要直接添加任何東西到你的關聯表中,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) 
    children = db.relationship("Student", 
        secondary=student_identifier) 

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

首先,student_identifier被定義爲SQLAlchemy的反射表不是數據庫。

通常情況下,如果您在模型和反射表對象之間正確設置了所有關係,則只需處理相關模型(通過將模型對象附加到關係InstrumentList中)以便將數據插入到反射表中,上面提供的答案@ 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語句之後,不要忘記在事務中完成後執行。

希望可以幫助您選擇另一種方法。