ความสับสนของการเชื่อมโยง SQLAlchemy

ฉันมีฐานข้อมูลนักเรียนใน SQLAlchemy พร้อมตารางต่อไปนี้

class Marks(Base):
    __table_args__ = {'extend_existing': True}
    __tablename__ = 'marks'
    id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
    mark = Column(Integer, nullable=False, unique=False)
    subject_fk = Column(Integer, ForeignKey('subjects.id'))
    subject = relationship('Subjects', foreign_keys=[locale_fk],uselist=False,
                          backref='marks', innerjoin=False, post_update=False)


class Subjects(Base):
    __table_args__ = {'extend_existing': True}
    __tablename__ = 'subjects'
    id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
    subject = Column(String(10, convert_unicode=True), nullable=False, unique=True)


class StudentIds(Base):
    __table_args__ = {'extend_existing': True}
    __tablename__ = 'student_ids'
    id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
    student_id = Column(String(50, convert_unicode=True), nullable=False,unique=False)


    junctionid = relationship("Junction", cascade='save-update',
                                     backref='student_ids', lazy='select', post_update=True)
    mk=relationship("Marks",secondary=lambda:junction_table)
    marks = association_proxy('mk', 'mark')


class Junction(Base):
    __table_args__ = {'extend_existing': True}
    __tablename__ = "junction_table"

    student_id_fk = Column(Integer, ForeignKey('student_ids.id'), primary_key=True)
    mark_fk = Column(Integer, ForeignKey('marks.id'), primary_key=True)
    mark = relationship('Marks', cascade='save-update', backref='mark_id_mapper', innerjoin=True)

ฉันมีข้อมูลที่บรรจุอยู่ในตาราง Student Ids, Marks และ Subjects.. ตอนนี้ ฉันต้องเติมข้อมูลในตารางเชื่อมต่อด้วย student_id และ mark คีย์ต่างประเทศ (เครื่องหมายที่ได้รับในแต่ละ หัวเรื่องถูกแทรกลงในตารางเครื่องหมาย) ฉันจะทำสิ่งนี้ได้อย่างไร ฉันหมายความว่าฉันสามารถสร้างพร็อกซีการเชื่อมโยงภายในตารางรหัสนักเรียนที่แมปกับตารางมาร์กและเติมข้อมูลลงในตารางนั้นได้

ฉันอ่านเอกสารนี้แล้ว: http://docs.sqlalchemy.org/en/rel_0_9/orm/extensions/associationproxy.html และฉันเข้าใจว่าฉันต้องการพรอกซีนี้ระหว่าง Student_id และเครื่องหมาย.. เพื่อที่ฉันจะสามารถสืบค้น Student_id.mark เพื่อรับเครื่องหมายได้ แต่ฉันจะเอามันไปไว้ในตาราง Junction ได้อย่างไร?

ใครช่วยกรุณาแนะนำฉันหน่อยได้ไหม?


person Tania    schedule 04.03.2015    source แหล่งที่มา


คำตอบ (1)


ฉันแนะนำว่ามันเป็นความสัมพันธ์แบบหนึ่งต่อหลาย (นักเรียนหนึ่งคน - หลายคะแนน http://docs.sqlalchemy.org/en/rel_0_9/orm/basic_relationships.html#one-to-many) ดังนั้นคุณอาจต้องการเพิ่ม Student_id ให้กับโมเดล Marks ของคุณและความสัมพันธ์กับ Marks ไปยังโมเดล StudentIds แทนที่จะสร้างโมเดล Junction

class StudentIds(Base):
    __table_args__ = {'extend_existing': True}
    __tablename__ = 'student_ids'
    id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
    student_id = Column(String(50, convert_unicode=True), nullable=False,unique=False)


    junctionid = relationship("Junction", cascade='save-update',
                                 backref='student_ids', lazy='select', post_update=True)
    marks = relationship("Marks", backref="student")


class Marks(Base):
    __table_args__ = {'extend_existing': True}
    __tablename__ = 'marks'
    id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
    mark = Column(Integer, nullable=False, unique=False)
    subject_fk = Column(Integer, ForeignKey('subjects.id'))
    subject = relationship('Subjects', foreign_keys=[subject_fk],uselist=False,
                      backref='marks', innerjoin=False, post_update=False)
    student_id = Column(Integer, ForeignKey('student_ids.id'))
    student = relationship('StudentIds', foreign_keys=[student_id])


class Subjects(Base):
    __table_args__ = {'extend_existing': True}
    __tablename__ = 'subjects'
    id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
    subject = Column(String(10, convert_unicode=True), nullable=False, unique=True)

หากคุณต้องการสร้างความสัมพันธ์แบบกลุ่มต่อกลุ่ม คุณอาจต้องการสร้างตารางการเชื่อมโยง (http://docs.sqlalchemy.org/en/rel_0_9/orm/basic_relationships.html#many-to-มากมาย)

association_table = Table('association', Base.metadata,
    Column('students_id', Integer, ForeignKey('student_ids.id')),
    Column('marks_id', Integer, ForeignKey('marks.id'))
)


class Marks(Base):
    __table_args__ = {'extend_existing': True}
    __tablename__ = 'marks'
    id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
    mark = Column(Integer, nullable=False, unique=False)
    subject_fk = Column(Integer, ForeignKey('subjects.id'))
    subject = relationship('Subjects', foreign_keys=[subject_fk],uselist=False, backref='marks', innerjoin=False, post_update=False)


class Subjects(Base):
    __table_args__ = {'extend_existing': True}
    __tablename__ = 'subjects'
    id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
    subject = Column(String(10, convert_unicode=True), nullable=False, unique=True)


class StudentIds(Base):
   __table_args__ = {'extend_existing': True}
   __tablename__ = 'student_ids'
   id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
   student_id = Column(String(50, convert_unicode=True), nullable=False,unique=False)


   junctionid = relationship("Junction", cascade='save-update',
                                 backref='student_ids', lazy='select', post_update=True)
   marks = relationship("Marks", secondary=association_table)

อย่างไรก็ตาม คุณไม่จำเป็นต้องมีโมเดล Junction เพื่อสร้างความสัมพันธ์ระหว่างนักเรียนกับคะแนนของพวกเขา

person Timur Osadchiy    schedule 04.03.2015
comment
แต่ตารางรวมคือที่ที่ฉันจะรวบรวมข้อมูลทั้งหมด สมมติว่า รหัสนักเรียน, รหัสเครื่องหมาย, รหัสหัวเรื่อง และคีย์ต่างประเทศทั้งหมดในที่เดียว.. หลังจากทั้งสามตารางนี้เต็มไปด้วยข้อมูลที่เกี่ยวข้องแล้ว ฉันจะนำพวกมันเข้าสู่ตารางเชื่อมต่อที่มีอยู่ได้อย่างไร การออกแบบข้างต้นที่คุณแนะนำนั้นยอดเยี่ยม แต่มีวิธีใช้ตารางแยกที่มีอยู่เพื่อเติมข้อมูลคีย์ต่างประเทศหรือไม่ - person Tania; 04.03.2015
comment
เพราะฉันอาจมีโมเดลใหม่สำหรับ 'ชั้นเรียนนักเรียน' ขึ้นมาด้วย ทุกชั้นเรียนจะมีรายการ Student_ids พร้อมด้วยรายการคะแนนของนักเรียนในแต่ละวิชา ในกรณีนี้ มันจะดีกว่าถ้าฉันมีตารางเชื่อมต่อที่มีคีย์ผสมเป็น Student_id และคลาส ตามด้วยคีย์ต่างประเทศของหัวเรื่องและคลาส การแทรกสามารถเป็นอิสระได้และโมเดลทางแยกควรเก็บข้อมูลที่รวมไว้ ฉันควรจะสอบถามเฉพาะตารางทางแยกในตอนท้าย มีวิธีการทำเช่นนี้หรือไม่? - person Tania; 04.03.2015
comment
หากคุณกำลังวางแผนที่จะมีโมเดล StudentClass มันจะมีความสัมพันธ์แบบกลุ่มต่อกลุ่มกับ StudentIds ดังนั้นคุณสามารถใช้แนวทางที่ฉันแนะนำข้างต้น (ตารางการเชื่อมโยง) จากนั้นคุณสามารถเพิ่ม StudentClass.id ให้กับโมเดล Mark ได้ ดังนั้นคุณจะสามารถรับรายการคะแนนสำหรับนักเรียนหรือชั้นเรียนหรือทั้งสองอย่างได้ ฉันจะไม่แนะนำให้ใช้โมเดล Junction นั้นอีกครั้ง - person Timur Osadchiy; 04.03.2015
comment
ใช้ได้. มีอีกหนึ่งคำชี้แจง สมมติว่าฉันต้องการข้อมูลสถานะในบางคอลัมน์ที่เรียกว่า ตรวจสอบแล้วสำหรับรหัสนักเรียน เครื่องหมาย และชั้นเรียนทุกรายการ คอลัมน์ที่ตรวจสอบแล้วนี้สามารถวางในตารางเชื่อมต่อได้ ดังนั้นหากฉันต้องการทราบข้อมูลสถานะของฟิลด์ใด ๆ ข้างต้น (sid, marks, class) ฉันสามารถสอบถามโมเดล Junction ได้ คุณช่วยแนะนำวิธีแก้ปัญหาสำหรับสิ่งนี้ได้ไหม นอกจากนี้ โมเดลชั้นเรียนนักเรียนของฉันสามารถเชื่อมโยงกับคะแนนของฉันเพื่อให้ได้รับคะแนนรวมทุกชั้นเรียนที่ได้รับ - person Tania; 04.03.2015
comment
หากผมทำให้คุณถูกแต่ละ Mark สำหรับแต่ละวิชาและ Student และ StudentClass อาจจะได้รับการตรวจสอบหรือไม่ จากนั้นได้รับการยืนยันว่าเป็นทรัพย์สินของ Mark และคุณต้องเพิ่มคอลัมน์บูลีนที่ได้รับการยืนยันอีกหนึ่งคอลัมน์ เมื่อคุณต้องการรับรายการ Marks สำหรับนักเรียน คุณเพียงแค่สอบถาม Mark model โดย StudentIds.id หากต้องการได้รับ Marks สำหรับชั้นเรียนเฉพาะสำหรับนักเรียนคนใดคนหนึ่ง คุณเพียงแค่สอบถามโมเดล Mark โดย StudentIds.id และ StudentClass.id - person Timur Osadchiy; 04.03.2015
comment
ใช่ ทุกอย่างขึ้นอยู่กับสถานะของเครื่องหมาย เมื่อพิจารณาถึงแนวทางของคุณแล้ว ฉันจำเป็นต้องมีฟิลด์ในตารางเครื่องหมาย แต่ฉันควรสร้างความสัมพันธ์ระหว่างมาร์คกับทุกสิ่งทุกอย่าง มาใส่กันเถอะ. ฉันมีข้อมูลวิชาและเครื่องหมายในแบบจำลอง Marks ของฉัน ฉันต้องบอกว่านักเรียนเกี่ยวข้องกับเครื่องหมายของเขาอย่างไร ถ้ามีคลาสใหม่เข้ามา มันจะกลายเป็น studentsxmarksxclass no.of items ซึ่งทำลายความเรียบง่ายของตารางเครื่องหมาย ซึ่งเป็นเหตุผลว่าทำไมฉันคิดว่าเราสามารถมีตารางที่มีเฉพาะฟิลด์คีย์ต่างประเทศและฟิลด์สถานะ ดังนั้นให้ทำความสะอาด/ แทรก กลายเป็นงานง่าย - person Tania; 04.03.2015
comment
ฉันเดาว่าตารางเครื่องหมายของเราจะกลายเป็นรูปแบบหนึ่งของโมเดลจุดเชื่อมต่อของเรา.. ซึ่งมีหัวเรื่อง, สถานะ, ข้อมูลเครื่องหมายทั้งหมดรวมอยู่ในที่เดียว ฉันจะแทรกตอนนี้ได้อย่างไร? ฉันจะใส่ Student_ids และมีคะแนนมากมายต่อข้อมูลวิชาในชั้นเรียน Mark ของฉัน ฉันจำเป็นต้องต่อท้ายสิ่งใดๆ Student-id.marks.append() เพื่อแทรกเครื่องหมายของนักเรียนทุกคนหรือไม่ ฉันมีไฟล์ CSV พร้อมรหัสนักศึกษาและเครื่องหมายที่ได้รับในทุกวิชา.. ช่อง: Studentid,mark1,mark2,mark3... ทีนี้ ฉันจะบอกได้อย่างไรว่า x Studentid ได้รับเครื่องหมาย x แล้ว และ,,, ฉันจะทำอย่างไรกับตารางการเชื่อมโยง? :( ตอนนี้สับสนมาก กรุณาชี้แจงด้วย - person Tania; 04.03.2015
comment
หากคุณใช้วิธีการแรกที่แนะนำในคำตอบของฉัน คุณไม่จำเป็นต้องสร้างตารางการเชื่อมโยงสำหรับแต่ละความสัมพันธ์ คุณเพียงแค่เพิ่มความสัมพันธ์กับ StudentIds, StudentClass และ Subject to the Mark model เช่นนี้: Student_id = Column(Integer, ForeignKey('student_ids.id')) นักเรียน = ความสัมพันธ์('StudentIds', Foreign_keys=[student_id]) - person Timur Osadchiy; 04.03.2015
comment
ขออภัยลืมยอมรับในขณะที่ +1 คำตอบของคุณ คุณช่วยได้มากอย่างแน่นอน .. สงสัยนิดหน่อย ฉันจะรับข้อมูล Student_id ลงในตารางเครื่องหมายของฉันได้อย่างไร หมายความว่า ฉันจะแทรกข้อมูลคีย์ต่างประเทศของ Student.id ลงไปเมื่อใด/อย่างไร ฉันรู้ว่าในขณะที่แทรกลงในตาราง Student_id ว่านักเรียนได้รับอะไร (ผ่านไฟล์ csv) ในเวลานั้น? คุณมีวิธีแทรกสิ่งเหล่านี้โดยใช้โมเดล Junction ของฉัน (ใน Initializedb ของฉัน) หรือไม่? - person Tania; 04.03.2015
comment
อย่างแน่นอน! คุณสร้างวัตถุนักเรียนในตอนแรก จากนั้นคุณสร้างอ็อบเจ็กต์ Mark ด้วย Student นั้น - person Timur Osadchiy; 04.03.2015