Flask-SQLAlchemy多对多关系,增删改查

SQLAlchemy

SQLAlchemy 是 Python 中一个通过 ORM 操作数据库的框架。
使用类和对象的方式操作数据库,更加简便相比SQL语句。
ORM 就是 Object Relational Mapper 的简写,就是关系对象映射器的意思。

创建映射关系

以王者荣耀为例,需要构建用户,英雄之间的关系。一个用户可以拥有多个英雄,一个英雄也可以被多个用户拥有。那么就需要三个表:用户,英雄,用户_英雄

创建数据库操作对象

需要引入的库

import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import or_, and_
app = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(24)
# url的格式为:数据库的协议://用户名:密码@ip地址:端口号(默认可以不写)/数据库名
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:123456@localhost/abcd"
# 动态追踪数据库的修改. 性能不好. 且未来版本中会移除. 目前只是为了解决控制台的提示才写的
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# 创建数据库的操作对象
db = SQLAlchemy(app)

用户类

class User(db.Model):
	# 给表重新定义一个名称,默认名称是类名的小写,比如该类默认的表名是user。
	__tablename__ = "user"
	id = db.Column(db.Integer, primary_key=True)
	name = db.Column(db.String(16), unique=True)
	password = db.Column(db.String(16))
	money = db.Column(db.String(16))
	diamonds = db.Column(db.String(16))
	heros = db.relationship('Hero', secondary=user_hero, backref=db.backref('users'))
	#这一句是设置多对多的关键地方
	#第一个参数'Hero',表示这个关系的另一端是Hero类
	#第二个参数secondary指向了中间表,中间表只包含关系的两侧表的主键列
	#第三个参数backref,表示反向引用
	def __repr__(self):
		return "User: %s %s %s %s" % (self.id, self.name, self.money, self.diamonds)

英雄类

class Hero(db.Model):
	__tablename__ = 'hero'
	id = db.Column(db.Integer, primary_key=True, autoincrement=True)
	name = db.Column(db.String(16), unique=True, nullable=False)
	type = db.Column(db.Integer)
	money = db.Column(db.Integer)
	diamonds = db.Column(db.Integer)
	img_url = db.Column(db.String(64))
	def __repr__(self):
		return "Hero: %s %s %s %s %s" % (self.id, self.name, self.money, self.diamonds,self.img_url)

用户_英雄中间表

#关联用户和英雄表
user_hero = db.Table('user_hero',
					 db.Column('user_id', db.Integer, db.ForeignKey('user.id'), primary_key=True),
					 db.Column('hero_id', db.Integer, db.ForeignKey('hero.id'), primary_key=True)
					 )

查询

#查询用户 小白 的信息
user=User.query.filter(User.name == '小白').first()

#查询用户 小白 拥有的英雄
user = User.query.filter(User.name=='小白').first()
heros = user.heros

#查询用户 小白 未拥有的英雄  cz存在,bz不存在
cz_hero_id = []
user = User.query.filter(User.name=='小白').first()
cz_hero = user.heros
for i in cz_hero:
	cz_hero_id.append(i.id)
bz_hero = db.session.query(Hero).filter(Hero.id.notin_(cz_hero_id)).all()

增加

#用户 小白 添加英雄 鲁班七号
user = User.query.filter(User.name=='小白').first()
hero=Hero.query.filter(Hero.name == '鲁班七号').first()
user.heros.append(hero)
db.session.commit()

删除

#删除主键为1的用户
user=User.query.get(1)
db.session.delete(user)
db.session.commit()

更新

#更新用户 小白 的金币
db.session.query(User).filter_by(name='小白').update({"money":'666'})
db.session.commit()

posted on 2020-05-18 22:16  Huhiseven  阅读(218)  评论(0编辑  收藏  举报

导航