如何使用SQLAlchemy的ORM模式构建表结构:一对一、一对多和多对多的关系
创作时间:
作者:
@小白创作中心
如何使用SQLAlchemy的ORM模式构建表结构:一对一、一对多和多对多的关系
引用
CSDN
1.
https://m.blog.csdn.net/qq_52964132/article/details/145483952
在 SQLAlchemy 的 ORM 模式中,可以通过定义类和关系来构建表结构,实现一对一、一对多和多对多的关系。以下是具体的实现方式:
1. 一对一关系(One-to-One)
一对一关系是指一个记录与另一个记录之间存在唯一对应关系。在 SQLAlchemy 中,可以通过 relationship
和 uselist=False
来实现。
示例代码
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, sessionmaker
Base = declarative_base()
class Person(Base):
__tablename__ = 'persons'
id = Column(Integer, primary_key=True)
name = Column(String)
# 定义一对一关系
passport = relationship("Passport", uselist=False, back_populates="person")
class Passport(Base):
__tablename__ = 'passports'
id = Column(Integer, primary_key=True)
passport_number = Column(String)
person_id = Column(Integer, ForeignKey('persons.id'))
# 反向引用
person = relationship("Person", back_populates="passport")
# 创建数据库引擎和会话
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
# 添加数据
person = Person(name="Alice")
passport = Passport(passport_number="123456789")
person.passport = passport
session.add(person)
session.commit()
# 查询
person = session.query(Person).first()
print(person.name, person.passport.passport_number)
2. 一对多关系(One-to-Many)
一对多关系是指一个记录可以与多个记录相关联。在 SQLAlchemy 中,可以通过 relationship
和 ForeignKey
来实现。
示例代码
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, sessionmaker
Base = declarative_base()
class Parent(Base):
__tablename__ = 'parents'
id = Column(Integer, primary_key=True)
name = Column(String)
# 定义一对多关系
children = relationship("Child", back_populates="parent")
class Child(Base):
__tablename__ = 'children'
id = Column(Integer, primary_key=True)
name = Column(String)
parent_id = Column(Integer, ForeignKey('parents.id'))
# 反向引用
parent = relationship("Parent", back_populates="children")
# 创建数据库引擎和会话
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
# 添加数据
parent = Parent(name="John")
child1 = Child(name="Alice")
child2 = Child(name="Bob")
parent.children.append(child1)
parent.children.append(child2)
session.add(parent)
session.commit()
# 查询
parent = session.query(Parent).first()
for child in parent.children:
print(parent.name, child.name)
3. 多对多关系(Many-to-Many)
多对多关系是指多个记录可以与多个记录相关联。在 SQLAlchemy 中,需要通过一个关联表来实现。
示例代码
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey, Table
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, sessionmaker
Base = declarative_base()
# 关联表
association_table = Table('association', Base.metadata,
Column('left_id', Integer, ForeignKey('left.id')),
Column('right_id', Integer, ForeignKey('right.id'))
)
class Left(Base):
__tablename__ = 'left'
id = Column(Integer, primary_key=True)
name = Column(String)
# 定义多对多关系
rights = relationship("Right", secondary=association_table, back_populates="lefts")
class Right(Base):
__tablename__ = 'right'
id = Column(Integer, primary_key=True)
name = Column(String)
# 反向引用
lefts = relationship("Left", secondary=association_table, back_populates="rights")
# 创建数据库引擎和会话
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
# 添加数据
left1 = Left(name="Left1")
left2 = Left(name="Left2")
right1 = Right(name="Right1")
right2 = Right(name="Right2")
left1.rights.append(right1)
left1.rights.append(right2)
left2.rights.append(right1)
session.add_all([left1, left2, right1, right2])
session.commit()
# 查询
left = session.query(Left).first()
for right in left.rights:
print(left.name, right.name)
总结
- 一对一:通过
relationship
和uselist=False
实现。 - 一对多:通过
relationship
和ForeignKey
实现。 - 多对多:通过一个关联表和
secondary
参数实现。
SQLAlchemy 的 ORM(对象关系映射)模式通过将数据库表映射到 Python 类,并利用类之间的关系来构建数据库结构。以下是上述三种关系实现的原理:
1. 一对一关系(One-to-One)
一对一关系是最简单的关系,表示两个表之间一对一的关联。通常通过 ForeignKey
和 relationship
来实现。
原理:
- 外键约束(ForeignKey):
- 在一个表中定义一个外键(外键列),关联到另一个表的主键。
- 例如,在
Passport
表中定义person_id
作为外键,关联到Person
表的主键id
。person_id = Column(Integer, ForeignKey('persons.id'))
- 双向关系(relationship):
- 在两个类之间使用
relationship
属性,通过back_populates
参数实现双向引用。 - 例如,
Person
类中的passport
属性和Passport
类中的person
属性相互引用。person = relationship("Person", back_populates="passport") passport = relationship("Passport", uselist=False, back_populates="person")
- 参数
uselist=False
表示该关系是一对一而非一对多。
- 数据库结构:
- 数据库中会生成两个表:
persons
和passports
。 passports
表中有一个外键列person_id
,指向persons
表的id
。
结果:
通过这种结构,每个 Person
对象只能有一个 Passport
对象,反之亦然。
2. 一对多关系(One-to-Many)
一对多关系是数据库中最常见的关系,表示一个记录可以关联到多个其他记录。
原理:
- 外键约束(ForeignKey):
- 在“多”的一方定义一个外键,关联到“一”的一方的主键。
- 例如,在
Child
表中定义parent_id
作为外键,关联到Parent
表的主键id
。parent_id = Column(Integer, ForeignKey('parents.id'))
- 双向关系(relationship):
- 在“一”的一方使用
relationship
属性,指定back_populates
参数。 - 在“多”的一方也使用
relationship
属性,通过外键关联到“一”的一方。# Parent类的一对多关系 children = relationship("Child", back_populates="parent") # Child类的反向关系 parent = relationship("Parent", back_populates="children")
- 数据库结构:
- 数据库中会生成两个表:
parents
和children
。 children
表中有一个外键列parent_id
,指向parents
表的id
。
结果:
通过这种结构,每个 Parent
对象可以关联多个 Child
对象,但每个 Child
对象只能关联一个 Parent
对象。
3. 多对多关系(Many-to-Many)
多对多关系表示多个记录可以同时关联到多个其他记录。这种关系通常通过一个关联表(中间表)来实现。
原理:
- 关联表(Association Table):
- 定义一个中间表,包含两个外键,分别关联到两个主表的主键。
- 例如,
association_table
包含left_id
和right_id
两个外键,分别关联到left
和right
表的主键。association_table = Table('association', Base.metadata, Column('left_id', Integer, ForeignKey('left.id')), Column('right_id', Integer, ForeignKey('right.id')) )
- 双向关系(relationship):
- 在两个主表中使用
relationship
属性,通过secondary
参数指定关联表。 - 使用
back_populates
参数实现双向引用。# Left类的多对多关系 rights = relationship("Right", secondary=association_table, back_populates="lefts") # Right类的反向关系 lefts = relationship("Left", secondary=association_table, back_populates="rights")
- 数据库结构:
- 数据库中会生成三个表:
left
、right
和association
。 association
表中包含两个外键列,分别指向left
和right
表的主键。
结果:
通过这种结构,Left
对象和 Right
对象可以相互关联,并且一个 Left
对象可以关联多个 Right
对象,反之亦然。
总结
- “One-to-One”:
- 通过外键和
relationship
实现一对一关系,uselist=False
确保关系为一对一。
- “One-to-Many”:
- 通过外键和
relationship
实现一对多关系,“一”的一方包含一个列表,用于存储“多”的一方的多个对象。
- “Many-to-Many”:
- 通过中间表和
relationship
的secondary
参数实现多对多关系,中间表存储两个表之间的关联。
热门推荐
沙坡头自驾游攻略:沙漠探险新体验
膨胀的二次元生意,与逐渐消失的“次元壁”
营养师推荐:糙米中的维生素B群补充法
维生素B缺乏竟引发抑郁?真相揭秘!
维生素B3过量致皮肤潮红?专家详解安全摄入量与副作用
具俊晔1.3万手环成大S最后礼物:我的爱,熙媛
上火怎么办?五种有效方式帮你调理去火
山楂荷叶茶的功效与饮用指南
揭秘AGM-114地狱火导弹:美军最新制导技术大曝光!
2025年天津土地市场:46宗重点地块释放新机遇
阿帕奇搭载地狱火导弹的秘密武器揭秘!
地狱火导弹:从海湾战争到现代战场的反装甲利器
长弓地狱火导弹:无人机终结者?
《星期三》第二季前瞻:珍娜·奥尔特加再演黑暗女王,波顿哥特美学再升级
珍娜·奥尔特加与凯瑟琳·泽塔-琼斯再续《星期三》第二季精彩
《星期三》:哥特文化的现代演绎
《王者荣耀》小乔背后的历史真相揭秘
国服榜一小乔深度教学:技能解析与实战技巧
王者荣耀:小乔最新技能组合攻略
职场小白必学:Ctrl键高效办公技巧
Ctrl+C/V/Z:高效办公的秘密武器
掌握Ctrl键,让你秒变职场高手!
妙佑医疗国际推荐:正确练习凯格尔运动
自贡“满园春”:一家老字号饮食店的变迁史
幼犬如厕训练全攻略:从入门到精通
违章停车如何申诉
依据法律法规怎样进行违章申诉?
营造和谐家庭氛围,提升亲子关系
家庭和谐:构建幸福生活的基石
婚姻家庭辅导:助力家庭和谐的社会新选择