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("订单标号为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表表名表名’
)
就不举栗子啦,道理差不多。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值