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()