您的位置:首页 > 编程语言 > Python开发

python-flask框架学习笔记(五)--一(多)对多关系映射在SQLAlchemy中的实现

2019-04-17 17:42 288 查看

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表表名表名’
)
就不举栗子啦,道理差不多。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐