關係資料庫是建立在關係模型基礎上的資料庫,所以表格之間的關係在資料庫程式設計中特別重要。本節圍繞在SQLAlchemy中如何定義關係及如何使用關係進行查詢進行講解,使讀者能夠快速掌握SQLAlchemy的關係操作。
1、案例
設計3個實體表:班級表class、學生表student、老師表teacher和1個關係表:class_teacher。班級與學生為一對多關係,班級與老師為多對多關係。
from sqlalchemy import Table,Column,Integer,ForeignKey,String from sqlalchemy.orm import relationship,backref from sqlalchemy.ext.declarative import declarative_base Base=declarative_base() class Class(Base): __tablename__='class' class_id=Column(Integer,primary_key=True) name=Column(String(50)) level=Column(Integer) address=Column(String(50)) class_teachers=relationship("ClassTeacher",backref="class") students=relationship("Student",backref="class") class Student(Base): __tablename__='student' student_id=Column(Integer,primary_key=True) name=Column(String(50)) age=Column(Integer) gender=Column(String(10)) address=Column(String(50)) class_id=Column(Integer,ForeignKey('class.id')) class Teacher(Base): __tablename__='teacher' teacher_id=Column(Integer,primary_key=True) name=Column(String(50)) gender=Column(String(10)) telephone=Column(String(50)) address=Column(String(50)) class_teachers=relationship("ClassTeacher",backref="teacher") class ClassTeacher(Base): __tablename__='class_teacher' teacher_id=Column(Integer,ForeignKey('teacher.teacher_id'),primary_key=True) class_id=Column(Integer,ForeignKey("class.id"),primary_key=True)
程式碼中用了4個SQLAlchemy模型對4個表進行了定義,其中與關係定義相關的部分如下:
外鍵設定:在列的定義中,為Column傳入ForeignKey進行外鍵設定。
class_id=Column(Integer,ForeignKey('class.id'))
關係設定:透過relationship關鍵字在父模型中建立對字表的引用,例如Class模型中的關係設定如下:
students=relationship("Student",backref="calss")
其中的backref參數為可選參數,如果設定backref,則此語句同時設定了從父表對子表的參考。
一對多關係的使用:以後可以直接透過該students屬性來獲得相關班級中所有學生的資訊。如下代碼可以列印班級【三年二班】的所有學生資料。
class=session.query(Class).filter(Clss.name=="三年二班").first() for student in class_.students: print(student)
多對多關係的使用:透過關聯模型ClassTeacher實現,在其中分別設定模型Class和Teacher的外鍵,並且在父模型中設置相應的relationship實現。多對多關係也可以想像成一個關聯表,分別對兩個父表實現了多對一的關係。班級與老師之間為多對多的關係,如下代碼可以打印班級【三年二班】中所有老師的信息
class=session.query(Class).filter(Class.name=="三年二班").first() for class_teacher in class_.class_teachers: teacher=class_teacher.teacher print(teacher)上述代碼中class_teacher.teacher是在模型teacher中針對ClassTeacher定義的反向引用。
2、連接查詢
在實際開發中,有了關係就必不可少地會有多表連接查詢的需求。下面透過實際範例示範如果進行多表連接查詢。
在查詢語句中可以使用join關鍵字進行連接查詢,列印所有三年級學生的姓名:
students=session.query(Student).join(Class).filter(Class.level==3).all() for student in students: print(student.namr)
上述查詢函數會自動把外鍵關係作為連接條件,該查詢被SQLAlchemy自動翻譯為如下SQL語句並執行:
SELECT student.student_id AS student_student_id, student.name AS student.name, student.age AS student.age, student.gender AS student.gender, student.address AS student.address, student.class_id AS student_class_id FROM student JOIN class ON student.class_id=class.class_id WHERE class.leve=? (3,)
如果需要將被連接表的內心同樣列印出來,則可以在query中指定多個表物件。
下面的語句在印出所有三年級學生姓名的同時,印出其所在班級的名字。
for student,class_ in session.query(Student,Class).join(Class).filter(Class.level==3).all(): print(student.name,class_.name)
上述查詢函數會自動把外鍵關係作為連接條件,該查詢會被SQLAlchemy自動翻譯為如下SQL語句並執行:
SELECT student.student_id AS student_student_id, student.name AS student.name, student.age AS student.age, student.gender AS student.gender, student.address AS student.address, student.class_id AS student_class_id, class.class_id AS class_class_id, class.name AS class_name, class.level AS class_level, class.address AS class_location FROM student JOIN class ON student.class_id=class.class_id WHERE class.leve=? (3,)
如果需要用除外鍵外的其他欄位作為連線條件,則需要開發者在join中自行設定。下面印出所有班級的address與學生的address相同的學生的姓名:
for student_name, in session.query(Student.name).join(Class,Class.address==Student.address).filter(Class.level==3).all(): print(student_name)
上述查詢函數根據開發者指定的語句作為連接條件,並且因為直接指定了被查詢的字段,所以減少了實際SQL中的被查詢字段,提高了效能。查詢被SQLAlchemy自動翻譯為如下SQL語句執行:
SELECT student.name AS student_name, FROM student JOIN class ON student.address=class.address
以上是Python下SQLAlchemy關係操作的介紹(附程式碼)的詳細內容。更多資訊請關注PHP中文網其他相關文章!