作者:长江7808 | 来源:互联网 | 2024-11-27 11:20
本文探讨了SQLAlchemyORM框架中如何利用外键和关系(relationship)来建立表间联系,简化复杂的查询操作。通过示例代码详细解释了relationship的定义、使用方法及其与外键的相互作用。
在SQLAlchemy ORM框架中,relationship用于定义模型类之间的关联关系,从而简化了跨表的数据查询操作。这种关联虽然不直接影响数据库的物理结构,但极大地增强了代码的可读性和维护性。
为了正确地使用relationship,必须先在相关表中定义外键(ForeignKey)。外键确保了数据库层面的数据完整性,而relationship则是在ORM层面上提供了一种更加直观的方式来处理这些关联数据。
如果没有正确设置外键,尝试使用relationship时将引发错误,例如:sqlalchemy.exc.NoForeignKeysError: Could not determine join condition between parent/child tables on relationship Father.son - there are no foreign keys linking these tables. Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or specify a ‘primaryjoin’ expression.
relationship的使用场景包括但不限于一对多、多对一、多对多等复杂的数据关系。通过定义relationship,可以直接访问关联表的数据,而无需显式执行JOIN操作,这不仅提高了查询效率,也使得代码更为简洁。
1 import sqlalchemy
2 from sqlalchemy import create_engine
3 from sqlalchemy import Column, String, Integer, ForeignKey
4 from sqlalchemy.orm import sessionmaker, relationship
5 from sqlalchemy.ext.declarative import declarative_base
6
7 engine = create_engine("mysql+pymysql://root:root@127.0.0.1/t1")
8
9 Base = declarative_base()
10
11 class Father(Base):
12 __tablename__ = "father"
13
14 id = Column(Integer, primary_key=True, autoincrement=True)
15 name = Column(String(40), unique=True)
16 age = Column(Integer)
17 sOns= relationship('Son', backref='father')
18
19 class Son(Base):
20 __tablename__ = 'son'
21
22 id = Column(Integer, primary_key=True, autoincrement=True)
23 name = Column(String(40), unique=True)
24 age = Column(Integer)
25 father_id = Column(Integer, ForeignKey('father.id'))
26
27 Base.metadata.create_all(engine)
28
29 Session = sessionmaker(bind=engine)
30 session = Session()
31
32 # 示例代码
33 father = Father(name='John Doe', age=35)
34 son1 = Son(name='Jane Doe', age=10, father=father)
35 son2 = Son(name='Jack Doe', age=8, father=father)
36 session.add_all([father, son1, son2])
37 session.commit()
38
39 # 查询父亲及其子女
40 father_query = session.query(Father).filter_by(id=1).first()
41 for son in father_query.sons:
42 print(f'Name: {son.name}, Age: {son.age}')
43
44 # 查询特定子的父
45 son_query = session.query(Son).filter_by(id=1).first()
46 print(f'Father Name: {son_query.father.name}, Father Age: {son_query.father.age}')
以上代码展示了如何通过relationship直接访问关联表的数据,避免了繁琐的JOIN操作,使代码更加简洁高效。