ORM是数据库映射模型,即把针对数据库的操作(增删改查等)抽象成了编程语言中代码的操作。例如:我想在数据库表User中增加一条记录,User_Class是User表在编程语言中的模型,我不需要去数据库中使用SQL命令,而是可以直接对User_Class进行操作,对数据库的操作交由User_Class自动完成,就像Qt中的QSqlTableModel这样的类。这就是数据库映射模型。
SQLAlchemy是一个很强大的关系型数据库框架。
Flask-SQLAlchemy是一个Flask扩展,简化了在Flask程序中使用SQLAlchemy的操作。
# pyCharm Terminal
pip install flask-sqlalchemy
看一个SQLite的例子:
# orm.py
from flask_sqlalchemy import SQLAlchemy
from flask import Flask
import os
basedir = os.path.abspath(os.path.dirname(__file__)) #获取当前文件所在的绝对路径
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///'+os.path.join(basedir,'data.sqlite') #拼接成URL
app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=False
db = SQLAlchemy(app)
db对象是SQLAlchemy类的实例,表示程序使用的数据库,同时还获得了Flask-SQLAlchemy的所有功能。
模型在这里用python的类表示,类的属性对应数据库表的列(column)。一个模型的实例对应一条记录 (record)。
看一个例子:
# orm.py
class Role(db.Model): #从db.Model中派生出Role类
__tablename__='roles' #指定model对应的表名
id = db.Column(db.Integer,primary_key=True) #定义一个属性,对应数据库表的列
name = db.Column(db.String,unique=True) #db.String表示此列数据类型,unique=True表示采用unique约束
users= db.relationship('User',backref='role')
def __ref__(self):
return '' %self.name
class User(db.Model):
__tablename__='users'
id = db.Column(db.Integer,primary_key=True)
username = db.Column(db.String,unique=True,index=True) #index约束为此列创建索引,提示查询速率
role_id = db.Column(db.Integer,db.ForeignKey('roles.id')) #db.ForeignKey('roles.id')表示与roles.id建立外键约束
def __ref__(self):
return '' %self.username
需要注意的是:users= db.relationship('User',backref='role'),backref参数向User模型中添加了一个role属性。这一属性可以访问Role模型,但是获取的是模型对象,不是外键的值。即:从User模型的实例(如user_john)可通过role属性直接访问到对应的role实例。
db.create_all() #创建数据库(地址和名字由URL指定 ),表名由定义的模型指定 (User和 Role)
如果有重名表存在数据库,不会重新创建或覆盖原表。也就是什么也不做。
db.drop_all()
因此,要更新同名表的方法就是删除,再新建 。(原数据会全丢失)
from orm import db
db.create_all()
from orm import Role,User
admin_role = Role(name='Admin')
mod_role = Role(name='Moderator')
user_role = Role(name='User')
user_john = User(username='john',role=admin_role)
user_susan = User(username='susan',role=mod_role)
首先,要创建模型的实例。
一个实例对应 一条 记录。
然后,添加到session(会话,实际是数据库的“事物操作”)。
db.session.add_all([admin_role,mod_role,user_role,user_john,user_susan,user_david])
最后,向数据库提交session(事物操作)
db.seesion.commit()
admin_role.name = 'Administrator'
db.session.add(admin_role)
db.session.commit()
db.session.delete(mod_role)
db.session.commit()
必须调用 db.session.commit()之后才会提交数据库。
Flask-SQLAlchemy为每个模型类都提供了query对象,用于查询。(all()属于执行函数)
query还提供了许多过滤器(函数):
常用查询过滤器:
最常使用的SQLAlchemy查询执行函数:
Q:前面都是从python对象(mod_role,user_john等)对数据库进行操作。如果拿到一个数据库,怎么拿到对应的python对象呢?
A:怎么拿到Model(对应表)暂时还不知道。
但是可以通过Model拿到实例(对应一条记录)。
role_temp = Role.query.filter_by(name='User').first()
print(role_temp is user_role)
结果为True!!!也就是说,role_temp就是之前创建的实例user_role!