表关系  

  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')  

 
 

多对多

  1.  # 多对多  
  2. from sqlalchemy import Table  
  3.   
     
  4. # 要创建一个多对多的关系表,首先需要一个中间表,通过Table来创建一个中间表  
  5. association_table = Table('teacher_classes',  # 中间表的表名  
  6.                           Base.metadata,  # Base的元类  
  7.                           Column('teacher_id', Integer, ForeignKey('teacher.id')),  
  8.                           Column('classes_id', Integer, ForeignKey('classes.id'))) # 要连接的两个表  
  9.                           # Column 第一个参数是表示的是连接表的外键名  
  10.                           # Column 第二个参数表示这个外键的类型  
  11.                           # Column 第三个参数表示要外键的表名和字段  
  12. class Teacher(Base):  
  13.     __tablename__ = 'teacher'  
  14.     id = Column(Integer,primary_key=True)  
  15.     name = Column(String(50))  
  16.     classes = relationship('Classes', secondary=association_table, back_populates='teachers')  # 通过secondary参数来连接中间表  
  17.   
     
  18.   
     
  19. class Classes(Base):  
  20.     __tablename__ = 'classes'  
  21.     id = Column(Integer,primary_key=True)  
  22.     name = Column(String(50))  
  23.     teachers = relationship('Teacher',secondary=association_table,back_populates='classes')  # 通过secondary参数来连接中间表 

例子

  1.  Base.metadata.create_all(engine)  
  2. Session = sessionmaker(engine)  
  3. db_session = Session()  
  4.   
     
  5. teacher1 = Teacher(name='Teacher1')  
  6. teacher2 = Teacher(name='teacher2')  
  7. classes1 = Classes(name='classes1')  
  8. classes2 = Classes(name='classes2')  
  9.   
     
  10. teacher1.classes = [classes1, classes2]  
  11. classes1.teachers = [teacher1]  
  12.   
     
  13. db_session.add(teacher1)  
  14. db_session.add(teacher2)  
  15. db_session.add(classes1)  
  16. db_session.add(classes2)  
  17.   
     
  18. db_session.close()  

Flask-sqlalchemy-表关系的更多相关文章

  1. ORM SQLAlchemy 表于表的关系

    1表与表之间三种关系 1.1 一对一关系 举例: 一个丈夫对应一个妻子,一个妻子对应一个丈夫 1.2 一对多关系 举例:一个人可以拥有多辆汽车,要求查询某个人拥有的所有车辆 分析:这种情况其实也可以采 ...

  2. flask SQLAlchemy中一对多的关系实现

    SQLAlchemy是Python中比较优秀的orm框架,在SQLAlchemy中定义了多种数据库表的对应关系, 其中一对多是一种比较常见的关系.利用flask sqlalchemy实现一对多的关系如 ...

  3. Python与数据库[2] -> 关系对象映射/ORM[5] -> 利用 sqlalchemy 实现关系表查询功能

    利用 sqlalchemy 实现关系表查询功能 下面的例子将完成一个通过关系表进行查询的功能,示例中的数据表均在MySQL中建立,建立过程可以使用 SQL 命令或编写 Python 适配器完成. 示例 ...

  4. SQLAlchemy(三):外键、连表关系

    SQLAlchemy03 /外键.连表关系 目录 SQLAlchemy03 /外键.连表关系 1.外键 2.ORM关系以及一对多 3.一对一的关系 4.多对多的关系 5.ORM层面的删除数据 6.OR ...

  5. flask建表遇到的错误: flask,sqlalchemy.exc.OperationalError: (MySQLdb._exceptions.OperationalError) (1071, 'Specified key was too long; max key length is 767 bytes')

    error:flask,sqlalchemy.exc.OperationalError: (MySQLdb._exceptions.OperationalError) (1071, 'Specifie ...

  6. day95:flask:SQLAlchemy数据库查询进阶&关联查询

    目录 1.数据库查询-进阶 1.常用的SQLAlchemy查询过滤器 2.常用的SQLAlchemy查询结果的方法 3.filter 4.order_by 5.count 6.limit&of ...

  7. Python之路第十三天,高级(7)-详述数据库一对多,多对多表关系的设计以及如何查询

    一对多表设计和查询方法 #!/usr/bin/env python3 # Author: Zhangxunan from sqlalchemy import create_engine from sq ...

  8. Python Django orm操作数据库笔记之外键和表关系

    外键 在MySQL中,表有两种引擎,一种是InnoDB,另外一种是myisam.如果使用的是InnoDB引擎,是支持外键约束的. 外键的使用 使用外键前需要先确保相应外键已存储在数据库中(flask中 ...

  9. tornado框架基础08-sqlalchemy表关系和简单登录注册

    01 一对一表关系 Module 需要先创建对应的 Module ,这里采用之前建立好的 User 和 UserDetails relationship from sqlalchemy.orm imp ...

  10. Flask – SQLAlchemy成员增加

    目录 简介 结构 展示 技术 运行 代码 创建数据库表单 views视图 home主页 添加成员addnew.html 展示页show_all 简介 结构 $ tree -I "__pyca ...

随机推荐

  1. 前端移动开发--viewpoint

    移动开发时,一般都会在头部加载这样一行meta标签 <meta name="viewport" content="width=device-width, initi ...

  2. [BZOJ1018][SHOI2008]堵塞的交通traffic 时间分治线段树

    题面 介绍一种比较慢的但是好想的做法. 网上漫天的线段树维护联通性,然后想起来费很大周折也很麻烦.我的做法也是要用线段树的,不过用法完全不同. 这个东西叫做时间分治线段树. 首先我们建一个\(1..m ...

  3. shell脚本特殊变量与变量子串相关知识

    一.shell脚本特殊变量 1.shell中常用特殊位置变量说明: $0 获取当前执行的shell脚本的文件名,如果执行脚本包含了路径,那么就包含了脚本路径 $n 获取当前执行的shell脚本的第n个 ...

  4. 【RabbitMQ】使用RabbitMQ实现延迟任务

    场景一:物联网系统经常会遇到向终端下发命令,如果命令一段时间没有应答,就需要设置成超时. 场景二:订单下单之后30分钟后,如果用户没有付钱,则系统自动取消订单. 上述类似的需求是我们经常会遇见的问题. ...

  5. springboot2集成redis5报错:io.lettuce.core.RedisException: io.lettuce.core.RedisConnectionException: DENIED Redis is running in protected

    报错信息如下: Caused by: io.lettuce.core.RedisException: io.lettuce.core.RedisConnectionException: DENIED ...

  6. 【HDU6609】Find the answer【线段树】

    题目大意:给你一个序列,对于每个i,你可以选择1~i-1中任意多的数并将它删去,剩余的数(包括i)∑≤m,问对于每个i最少删几个数可以达到要求 题解: 考虑朴素的思想,对于每个i,我只需要删去最大的若 ...

  7. flutte页面布局四

    AspectRatio 组件 AspectRatio 的作用是根据设置调整子元素 child 的宽高比. AspectRatio 首先会在布局限制条件允许的范围内尽可能的扩展,widget 的高度是由 ...

  8. cannot access Input/output error

    ls: cannot access  Input/output errorls: cannot open directory .: Input/output error 硬盘故障,只读或只写,你可以d ...

  9. moment.js 时间库

    一.概念:    https://www.cnblogs.com/Jimc/p/10591580.html    或    http://momentjs.cn/(官网) 1.Moment.js是一个 ...

  10. [CSP-S模拟测试]:蔬菜(二维莫队)

    题目描述 小$C$在家中开垦了一块菜地,可以抽象成一个$r\times c$大小的矩形区域,菜地的每个位置都种着一种蔬菜.秋天到了,小$C$家的菜地丰收了. 小$C$拟定了$q$种采摘蔬菜的计划,计划 ...