Flask-sqlalchemy-表关系

本文介绍了SQLAlchemy ORM中如何模拟表关系,包括一对一、一对多和多对多关系的实现。通过示例展示了ForeignKey的使用,以及如何在ORM层面定义和绑定这些关系。例如,创建了User和Address表,演示了如何建立User与多个Address的一对多关系,以及如何设置一对一关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

表关系  

  1. 表之间的关系存在三种:  

  2. 一对一、一对多、多对多。  

  3. 而SQLAlchemy中的ORM也可以模拟这三种关系。因为一对一其实在SQLAlchemy中底层是通过一对多的方式模拟的,  

  4. 所以先来看下一对多的关系  

 

ForeignKey

  1. # -*- coding: utf-8 -*-  

  2. from sqlalchemy.ext.declarative import declarative_base  

  3. from sqlalchemy import Column # 列  

  4. from sqlalchemy import Integer, String, ForeignKey  # 属性  

  5. from sqlalchemy import create_engine  

  6. from sqlalchemy.orm import relationship #  

  7.     

  8. Base = declarative_base()  # django models  

  9.     

  10. class Article(Base):  

  11.     __tablename__ = "article"  

  12.     

  13.     id = Column(Integer, primary_key=True, autoincrement=True)  

  14.     title = Column(String(30), nullable=False)  

  15.     content = Column(String(30), nullable=False)  

  16.     uid = Column(Integer, ForeignKey('user.id'))  

  17.     

  18.     def __repr__(self):  

  19.         return "<Article(title:%s)>" % self.title  

  20.     

  21.     

  22. class Users(Base):  

  23.     __tablename__ = 'user'  

  24.     id = Column(Integer, primary_key=True, autoincrement=True)  

  25.     username = Column(String(50), nullable=False)  

  26.     

  27. engine = create_engine("mysql+pymysql://root:redhat@192.168.32.71:3306/my_sql?charset=utf8")  

  28. # 去engine数据库中创建所有继承Base的表  

  29. Base.metadata.create_all(engine)  

  30.     

  31.     

  32. 外键约束有以下几项:  

  33.     

  34.     RESTRICT:父表数据被删除,会阻止删除。默认就是这一项。  

  35.     NO ACTION:在MySQL中,同RESTRICT。  

  36.     CASCADE:级联删除。  

  37.     SET NULL:父表数据被删除,子表数据会设置为NULL。

 

一对多

  1. # 一对多  

  2. class Address(Base):  

  3.     __tablename__ = 'address'  

  4.     id = Column(Integer, primary_key=True)  

  5.     email_address = Column(String(30), nullable=False)  

  6.     

  7.     # FK  

  8.     # User表的外键,指定外键的时候,是使用的是数据库表的名称,而不是类名  

  9.     user_id = Column(Integer, ForeignKey('users.id'))  

  10.     

  11.     # 在ORM层面绑定两者之间的关系,第一个参数是绑定的表的类名,  

  12.     # 第二个参数back_populates是通过User反向访问时的字段名称  

  13.     user = relationship('User', back_populates="addresses")  

  14.     

  15.     def __repr__(self):  

  16.         return "<Address(email_address='%s')>" % self.email_address  

  17.     

  18.     

  19. class User(Base):  

  20.     __tablename__ = 'users'  

  21.     id = Column(Integer, primary_key=True)  

  22.     name = Column(String(50))  

  23.     

  24.     # 在ORM层面绑定和`Address`表的关系  

  25.     addresses = relationship("Address", order_by=Address.id, back_populates="user")  

  26.     

  27. # 注意:  

  28. # 在User表中添加的addresses字段,可以通过User.addresses来访问和这个user相关的所有address  

  29. # 在Address表中的user字段,可以通过Address.user来访问这个user。达到了双向绑定  

例子

  1. Session = sessionmaker(engine)  

  2. db_session = Session()  

  3.     

  4. peach = User(name='peach')  

  5. peach.addresses = [Address(email_address='1234@qq.com'),  

  6.                    Address(email_address='2345@qq.com')]  

  7.     

  8. db_session.add(peach)  

  9. db_session.commit()  

  10. db_session.close() 

 

一对一

  1. # 一对一  

  2. class Address(Base):  

  3.     __tablename__ = 'addresses'  

  4.     id = Column(Integer, primary_key=True)  

  5.     email_address = Column(String(50))  

  6.     user_id = Column(Integer, ForeignKey('users.id'))  

  7.     user = relationship('User', back_populates='addresses')  

  8.     

  9. class User(Base):  

  10.     __tablename__ = 'users'  

  11.     id = Column(Integer,primary_key=True)  

  12.     name = Column(String(50))  

  13.     # 设置uselist关键字参数为False  

  14.     addresses = relationship("Address", back_populates='user', uselist=False)  

  15.     

  16. # 只要在User表中的addresses字段上添加uselist=False就可以达到一对一的效果  

  17. # 设置了一对一的效果后,就不能添加多个邮箱到user.addresses字段了  

例子

  1. peach = User(name='peach')  

  2. peach.addresses = Address(email_address='1234@qq.com')  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值