python-flask框架学习笔记(五)--一(多)对多关系映射在SQLAlchemy中的实现
1.一对多关系
如果A表中的一条数据可以关联到B表中的多条数据,而且B表中的一条数据可以关联到A表中的一条条数据,就叫一对多关系
比如:一个客户可以对应多个订单,一个订单只能属于一个客户。这个时候客户就是一,订单就是多。
不会判断谁是多谁是一的话可以这样来写一写
OrderID(一个) ---- CustomerID(一个)
CustomerID(一个) ---- OrderID(多个)
一对多关系在数据库中靠主键和外键来实现,在一中创建主键,在多中创建外键来表示对一中主键的引用。
3.在SQLAlchemy中也差不多,在““多” 的实体类中增加对 一 的实体类的引用(外键),但是增加了一点,就是在一的实体类中
增加““关联属性"以及"反向引用关系属性”
举个栗子
from flask import Flask from flask_script import Manager from flask_migrate import Migrate,MigrateCommand from flask_sqlalchemy import SQLAlchemy import sqlalchemy import pymysql pymysql.install_as_MySQLdb app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:123456@localhost:3306/flask' app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True app.config['DEBUG'] = True app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False #创建SQLAlchemy的实例 db = SQLAlchemy(app) #将app交给Manager进行管理 manager = Manager(app) #创建一个Migrate的对象,指定关联的app和db migrate = Migrate(app,db) manager.add_command('db',MigrateCommand) #创建一个oders表和一个customer表 class Order(db.Model): __tablename__ = "orders" oderID = db.Column(db.Integer,primary_key=True,autoincrement=True) odate = db.Column(db.Date,unique=True,nullable=False) oamount = db.Column(db.Integer,unique=True,nullable=False) #在多表中创建外建对应一表的主键 cID = db.Column(db.Integer,db.ForeignKey('customer.customerID')) class Customer(db.Model): __tablename__ = 'customer' customerID = db.Column(db.Integer,primary_key=True) cname = db.Column(db.String(20),nullable=False) ctel = db.Column(db.Integer,nullable=False,unique=True) #在一表中增加关联属性和反向引用关系属性 oders = db.relationship("Order",backref = 'c_orders',lazy='dynamic') db.create_all() if __name__ == '__main__': manager.run()
shell中的指令(最后发一次啦~ 记住顺序:db init/migrate/upgrade) 然后runserver
运行之后来看一看数据库里面
好了,欧了,来看看语法
语法:
1.在“”"多"的实体类中
增加一个列/属性,引用自"一"表/类的主键列/属性
外键列名 = db.Column(
db.TYPE,
db.ForeignKey(‘主键表.主键列’)
)
2.在“"一"的实体类中
增加关联属性和反向引用关系属性,关联属性是指在"一"的实体中,要通过哪个<<属性>>来获取到对应的"多"的实体对象们
反向引用关系属性是指在“”“”"多"的实体中,要通过哪个<<属性>>来获取到对应的"一"的实体对象
语法
属性名 = db.relationship(
“多的实体类名”,
backref = ‘反向引用关系属性名(自定义)’,
lazy=‘dynamic’
)
*lazy:指定如何加载相关记录,有以下几种方法:
1.select 首次访问源对象时加载关联数据
2,immediate 源对象加载后立即加载相关数据(使用连接)
3.subquery 同上(使用子查询)
4.noload 永不加载
5.dynamic 用的时候加载,不用的时候不加载,是目前用得最多的一种。
然后举个栗子演示下反向引用关系属性是怎么使用的
from flask import Flask from flask_script import Manager from flask_migrate import Migrate,MigrateCommand from flask_sqlalchemy import SQLAlchemy import sqlalchemy import pymysql pymysql.install_as_MySQLdb import datetime app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:123456@localhost:3306/flask' app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True app.config['DEBUG'] = True app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False #创建SQLAlchemy的实例 db = SQLAlchemy(app) #将app交给Manager进行管理 manager = Manager(app) #创建一个Migrate的对象,指定关联的app和db migrate = Migrate(app,db) manager.add_command('db',MigrateCommand) #创建一个叫student的表,属性有id(整数型,主键,自动增长),学生姓名sname(长度为30的字符型,不允许为空), #学生年龄sage(整数型,不允许为空) class Order(db.Model): __tablename__ = "orders" oderID = db.Column(db.Integer,primary_key=True,autoincrement=True) odate = db.Column(db.Date,unique=True,nullable=False) oamount = db.Column(db.Float,unique=True,nullable=False) #在多表中创建外建对应一表的主键 cID = db.Column(db.Integer,db.ForeignKey('customer.customerID')) class Customer(db.Model): __tablename__ = 'customer' customerID = db.Column(db.Integer,primary_key=True) cname = db.Column(db.String(20),nullable=False) ctel = db.Column(db.Integer,nullable=False,unique=True) #在一表中增加关联属性和反向引用关系属性 orders = db.relationship("Order",backref = 'c_orders',lazy='dynamic') #事先要向customer表中插入一条customerID为1,cname为taobao,ctel为1000的记录 现在像orders表里面插入一条记录,cid=1 orders = Order() orders.oderID = 10001 t1 = datetime.datetime.date(datetime.datetime.now()) orders.odate = t1 orders.oamount = 666.6 cID = 1 db.session.add(orders) #查找customerID=1的客户信息 customer = Customer.query.filter_by(customerID=1).first() orders.c_orders = customer db.session.add(orders) #利用反向关系属性就可以在orders表中查找出customer的信息了 orders2 = Order.query.filter_by(oderID = 10001).first() print(" 3ff7 订单标号为10001的订单对应的客户是%s" % orders2.c_orders.cname) if __name__ == '__main__': manager.run()
看下结果
2.多对多关系
2.多对多
多对多其实也很简单,当A表和B表是多对多关系时,我们创建一个C表即可,
然后在AB任意一个表中增加一个属性
属性名 = db.relationship(
‘关联类名’,
lazy=‘dynamic’,
backref=db.backref(‘反向引用属性名’,lazy=‘dynamic’),
secondary=‘C表表名表名’
)
就不举栗子啦,道理差不多。
- Python ORM框架SQLAlchemy学习笔记之关系映射实例
- Python ORM框架SQLAlchemy学习笔记之关系映射实例
- [原创]java WEB学习笔记85:Hibernate学习之路-- -映射 一对一关系 ,基于主键方式实现
- 【python学习笔记】flask实现简单的接收json返回json的接口
- Python Flasky学习_使用Flask_SQLAlchemy的asPagination类对象实现分页
- Python Flask框架连接Mysql 学习笔记
- python-flask框架学习笔记(七)--完整的flask框架怎么写
- python学习教程(九)sqlalchemy框架的modern映射
- python学习教程(九)sqlalchemy框架的modern映射
- Python学习笔记2-flask-sqlalchemy 简单笔记
- 基于python的web框架——Flask 学习笔记
- [原创]java WEB学习笔记84:Hibernate学习之路-- -映射 一对一关系 ,基外键的方式实现
- 三十五、python学习之Flask框架(七)数据库:Flask对数据库的基本操作、常见关系模板、数据库迁移、综合案例:图书管理
- C#.Net Castle ActiveRecord学习实践(5):实现Many–Many关系的映射
- ListView,CursorAdapter,ContextMenu之间的映射关系学习笔记。
- 一个无聊男人的疯狂《数据结构与算法分析-C++描述》学习笔记 用C++/lua/python/bash的四重实现(5)欧几里得算法欧几里得算法求最大公约数
- Castle ActiveRecord学习实践(5):实现Many–Many关系的映射
- Hibernate学习笔记_关系映射_其他
- Castle ActiveRecord学习实践(4):实现One-Many关系的映射
- 云计算学习笔记---Hadoop简介,hadoop实现原理,NoSQL介绍...与传统关系型数据库对应关系,云计算面临的挑战