Flask-sqlalchemy-表关系
表关系
- 表之间的关系存在三种:
- 一对一、一对多、多对多。
- 而SQLAlchemy中的ORM也可以模拟这三种关系。因为一对一其实在SQLAlchemy中底层是通过一对多的方式模拟的,
- 所以先来看下一对多的关系
ForeignKey
- # -*- coding: utf-8 -*-
- from sqlalchemy.ext.declarative import declarative_base
- from sqlalchemy import Column # 列
- from sqlalchemy import Integer, String, ForeignKey # 属性
- from sqlalchemy import create_engine
- from sqlalchemy.orm import relationship #
- Base = declarative_base() # django models
- class Article(Base):
- __tablename__ = "article"
- id = Column(Integer, primary_key=True, autoincrement=True)
- title = Column(String(30), nullable=False)
- content = Column(String(30), nullable=False)
- uid = Column(Integer, ForeignKey('user.id'))
- def __repr__(self):
- return "<Article(title:%s)>" % self.title
- class Users(Base):
- __tablename__ = 'user'
- id = Column(Integer, primary_key=True, autoincrement=True)
- username = Column(String(50), nullable=False)
- engine = create_engine("mysql+pymysql://root:redhat@192.168.32.71:3306/my_sql?charset=utf8")
- # 去engine数据库中创建所有继承Base的表
- Base.metadata.create_all(engine)
- 外键约束有以下几项:
- RESTRICT:父表数据被删除,会阻止删除。默认就是这一项。
- NO ACTION:在MySQL中,同RESTRICT。
- CASCADE:级联删除。
- SET NULL:父表数据被删除,子表数据会设置为NULL。
一对多
- # 一对多
- class Address(Base):
- __tablename__ = 'address'
- id = Column(Integer, primary_key=True)
- email_address = Column(String(30), nullable=False)
- # FK
- # User表的外键,指定外键的时候,是使用的是数据库表的名称,而不是类名
- user_id = Column(Integer, ForeignKey('users.id'))
- # 在ORM层面绑定两者之间的关系,第一个参数是绑定的表的类名,
- # 第二个参数back_populates是通过User反向访问时的字段名称
- user = relationship('User', back_populates="addresses")
- def __repr__(self):
- return "<Address(email_address='%s')>" % self.email_address
- class User(Base):
- __tablename__ = 'users'
- id = Column(Integer, primary_key=True)
- name = Column(String(50))
- # 在ORM层面绑定和`Address`表的关系
- addresses = relationship("Address", order_by=Address.id, back_populates="user")
- # 注意:
- # 在User表中添加的addresses字段,可以通过User.addresses来访问和这个user相关的所有address
- # 在Address表中的user字段,可以通过Address.user来访问这个user。达到了双向绑定
例子
- Session = sessionmaker(engine)
- db_session = Session()
- peach = User(name='peach')
- peach.addresses = [Address(email_address='1234@qq.com'),
- Address(email_address='2345@qq.com')]
- db_session.add(peach)
- db_session.commit()
- db_session.close()
一对一
- # 一对一
- class Address(Base):
- __tablename__ = 'addresses'
- id = Column(Integer, primary_key=True)
- email_address = Column(String(50))
- user_id = Column(Integer, ForeignKey('users.id'))
- user = relationship('User', back_populates='addresses')
- class User(Base):
- __tablename__ = 'users'
- id = Column(Integer,primary_key=True)
- name = Column(String(50))
- # 设置uselist关键字参数为False
- addresses = relationship("Address", back_populates='user', uselist=False)
- # 只要在User表中的addresses字段上添加uselist=False就可以达到一对一的效果
- # 设置了一对一的效果后,就不能添加多个邮箱到user.addresses字段了
例子
- peach = User(name='peach')
- peach.addresses = Address(email_address='1234@qq.com')
多对多
- # 多对多
- from sqlalchemy import Table
- # 要创建一个多对多的关系表,首先需要一个中间表,通过Table来创建一个中间表
- association_table = Table('teacher_classes', # 中间表的表名
- Base.metadata, # Base的元类
- Column('teacher_id', Integer, ForeignKey('teacher.id')),
- Column('classes_id', Integer, ForeignKey('classes.id'))) # 要连接的两个表
- # Column 第一个参数是表示的是连接表的外键名
- # Column 第二个参数表示这个外键的类型
- # Column 第三个参数表示要外键的表名和字段
- class Teacher(Base):
- __tablename__ = 'teacher'
- id = Column(Integer,primary_key=True)
- name = Column(String(50))
- classes = relationship('Classes', secondary=association_table, back_populates='teachers') # 通过secondary参数来连接中间表
- class Classes(Base):
- __tablename__ = 'classes'
- id = Column(Integer,primary_key=True)
- name = Column(String(50))
- teachers = relationship('Teacher',secondary=association_table,back_populates='classes') # 通过secondary参数来连接中间表
例子
- Base.metadata.create_all(engine)
- Session = sessionmaker(engine)
- db_session = Session()
- teacher1 = Teacher(name='Teacher1')
- teacher2 = Teacher(name='teacher2')
- classes1 = Classes(name='classes1')
- classes2 = Classes(name='classes2')
- teacher1.classes = [classes1, classes2]
- classes1.teachers = [teacher1]
- db_session.add(teacher1)
- db_session.add(teacher2)
- db_session.add(classes1)
- db_session.add(classes2)
- db_session.close()
Flask-sqlalchemy-表关系的更多相关文章
- ORM SQLAlchemy 表于表的关系
1表与表之间三种关系 1.1 一对一关系 举例: 一个丈夫对应一个妻子,一个妻子对应一个丈夫 1.2 一对多关系 举例:一个人可以拥有多辆汽车,要求查询某个人拥有的所有车辆 分析:这种情况其实也可以采 ...
- flask SQLAlchemy中一对多的关系实现
SQLAlchemy是Python中比较优秀的orm框架,在SQLAlchemy中定义了多种数据库表的对应关系, 其中一对多是一种比较常见的关系.利用flask sqlalchemy实现一对多的关系如 ...
- Python与数据库[2] -> 关系对象映射/ORM[5] -> 利用 sqlalchemy 实现关系表查询功能
利用 sqlalchemy 实现关系表查询功能 下面的例子将完成一个通过关系表进行查询的功能,示例中的数据表均在MySQL中建立,建立过程可以使用 SQL 命令或编写 Python 适配器完成. 示例 ...
- SQLAlchemy(三):外键、连表关系
SQLAlchemy03 /外键.连表关系 目录 SQLAlchemy03 /外键.连表关系 1.外键 2.ORM关系以及一对多 3.一对一的关系 4.多对多的关系 5.ORM层面的删除数据 6.OR ...
- 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 ...
- day95:flask:SQLAlchemy数据库查询进阶&关联查询
目录 1.数据库查询-进阶 1.常用的SQLAlchemy查询过滤器 2.常用的SQLAlchemy查询结果的方法 3.filter 4.order_by 5.count 6.limit&of ...
- Python之路第十三天,高级(7)-详述数据库一对多,多对多表关系的设计以及如何查询
一对多表设计和查询方法 #!/usr/bin/env python3 # Author: Zhangxunan from sqlalchemy import create_engine from sq ...
- Python Django orm操作数据库笔记之外键和表关系
外键 在MySQL中,表有两种引擎,一种是InnoDB,另外一种是myisam.如果使用的是InnoDB引擎,是支持外键约束的. 外键的使用 使用外键前需要先确保相应外键已存储在数据库中(flask中 ...
- tornado框架基础08-sqlalchemy表关系和简单登录注册
01 一对一表关系 Module 需要先创建对应的 Module ,这里采用之前建立好的 User 和 UserDetails relationship from sqlalchemy.orm imp ...
- Flask – SQLAlchemy成员增加
目录 简介 结构 展示 技术 运行 代码 创建数据库表单 views视图 home主页 添加成员addnew.html 展示页show_all 简介 结构 $ tree -I "__pyca ...
随机推荐
- 前端每日实战:63# 视频演示如何用纯 CSS 创作一台烤面包机
效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/OEBJRN 可交互视频 此视频是可 ...
- 最新Zip压缩文件漏洞,黑客可以触发目录遍历攻击
近日,国内某安全公司研究人员透露了一个关键漏洞的详细信息,该漏洞影响了许多生态系统中的数千个项目,黑客可以利用这些漏洞在目标系统上实现代码执行. 黑客是如何通过Zip压缩文件入侵攻击?被称为“ZipS ...
- SERVLET API中转发与重定向的区别?
SERVLET API中转发与重定向的区别? 1.转发(forward方法) 转发仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址. 转发是服务器请求资源,服务器直接访问目标地址的 ...
- 数据库与缓存:3.mongodb的基本知识
1. mongodb是什么? NoSQL 非关系型数据库,主要用于数据的海量存储.分为server数据存储端和client数据操作端. 1.1 关系型与非关系型数据库的区别? 1.sql:数据库--表 ...
- VUE中使用canvas做签名功能,兼容IE
<template> <div> <div class="msgInput"> &l ...
- jenkins 更改端口
方法一 在Jenkins目录下,运行一下命令: java -jar jenkins.war --ajp13Port=-1 --httpPort=8081 出现了错误: C:\Program Files ...
- flask01
-python中的web框架 -a:socket服务端 b:路由转发 c:模板渲染 -Django:a:用了别人的 b,c自己写的 -Flask:a:用了别人的 b自己写的,c:用了别人的: jinj ...
- Python爬虫之抓取豆瓣影评数据
脚本功能: 1.访问豆瓣最受欢迎影评页面(http://movie.douban.com/review/best/?start=0),抓取所有影评数据中的标题.作者.影片以及影评信息 2.将抓取的信息 ...
- spfa模板(洛谷3371)
洛谷P3371 //spfa:求s到各点的最短路,可含负权边 #include <cstdio> using namespace std; ,max_m=,inf=; struct ety ...
- linux 文件及目录结构体系
linux 目录的特点: 1). /是所有目录的顶点 2).目录结构像一颗倒挂的树 3).目录和磁盘分区是没有关联的 4)./下不同的目录可能对应不同的分区或磁盘 5).所有的目录都是按照一定的类别有 ...