模型 (models) 是对数据抽象并提供通用访问接口的一种方式。
在大多数网络应用中,数据会被存储在一个关系数据库管理系统 (RDBMS) 中,也就是把数据格式化存储在由行与列组成的表格中,且能够跨表对数据进行比较。例如 MySQL、Postgress、Oracle 和 MSSQL。
为了基于数据库抽象出数据模型,我们需要使用一个叫做 SQLAlchemy 的 Python 包。SQLAlchemy 在底层包装了数据库操作接口,在最上层提供了对象关系映射 (ORM)。
ORM 是在基于不同的数据结构和系统类型的数据源之间传递和转换数据的技术在这里,它用来把大量的不同类型的数据库中的数据,转换成 Python 对象的集合。同时,像 Python 这样的语言,允许你在不同的对象之间建立引用,读取和设置它们的属性;而 SQLAlchemy 这样的 ORM,能为你将操作对象转换为传统的数据库操作。
Flask SQLAlchemy 在SQLAlchemy上提供了一层包装,这样就可以结合 Flask 的一些特性来方便地调用 SQLAlchemy 的功能。
SQLAlchemy 不但允许我们根据数据库表结构创建数据模型 (model),也允许我们根据数据模型创建数据库表结构。所以当我们把第一个模型创建出来之后,表结构也就有了。
首先,要在main.py
文件中将我们的 app 对象传给 SQLAlchemy,将 SQLAlchemy 初始化:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
db = SQLAlchemy(app)
SQLAlchemy 会从 app 的配置中读取信息,自动连接到数据库。我们首先在main.py
中创建一个 User 模型,它会跟相应的一个 user 表进行交互。
在main.py
中创建一个User模型:
class User(db.Model):
# SQLAlchemy 会假设你的表名就是模型类名的小写版本
# 设置表名
# __table__ = 'user_info'
id = db.column(db.Integer, primary_key=True)
# primary_key 参数会告诉 SQLAlchemy, 这个字段需要做主键索引
username = db.Column(db.String(255))
password = db.Column(db.String(255))
故此,我们得到一个User模型,它基于一个 user 表,该表拥有三个字段。
当我们继承 db.Model 时,与数据库连接和通信的工作已经自动完成了。
User的某些类的属性值是 db.Column 类的实例,每个这样的属性都代表了数据库表里的一个字段。在 db.Column 的构造函数里,第一个参数是可选的,通过这个参数,我们可以指定该属性在数据库中的字段名。如果没有指定,则 SQLAlcemy 会认为字段名与这个属性的名字是一样的。如果要指定这个可选参数,则可以这样写:
username = db.Column('username', db.String(255))
传给 SQLAlchemy 的第二个参数会告诉 SQLAlchemy,应该把这个字段作为什么类型来处理。
db.create_all()
见单个数据表的创建/删除以及增删改查
class User(db.Model):
__tablename__ = "网站用户"
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(30), unique=True, index=True, nullable=False) # unique=True用户名不能重复
password = db.Column(db.String(20), nullable=False)
email = db.Column(db.String(20), unique=True, index=True)
# 设置默认值, 位当前用户的创建时间;
add_time = db.Column(db.DateTime, default=datetime.now())
#### 重要的: 用户角色id不能随便设置, 需要从Role中查询, (外键关联)
role_id = db.Column(db.Integer, db.ForeignKey('用户角色.id'))
# 定义了 __repr()__ 方法,返回一个具有可读性的字符串表示模型,可在调试和测试时使用。
def __repr__(self):
return "" % (self.username)
注意 User 类中的 role_id 字段,关系型数据库中,ForeignKey 表示一个外键约束 (Foreign Key Constraint)。外键约束是数据库中的一种约束规则,在这里,它强制要求 role_id 字段的值存在于用户角色表的 id 列中。这是数据库进行的一项检查,用来保证每个 User 对象都会对应到一个已有的用户角色。传给 db.ForeignKey 的参数,是一个用来代表用户角色表 id 列的字符串。 如果你要用__tablename__自定义表名,则需要同时修改这个字符串。之所以直接用表名,而不是使用 Role.id 引用,是因为在 SQLAlchemy 初始化期间,Role 对象可能还没有被创建出来。
role_id 字段还不足以让 SQLAlchemy 建立我们想要的关联,我们还需要这样修改 Role 对象:
class Role(db.Model):
__tablename__ = "用户角色"
# id号递增autoincrement=True
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(20))
# 反向引用, Role表中有属性users, User类中有role这个属性
users = db.relationship('User', backref='role')
def __repr__(self):
return "" % (self.name)
db.relationship 函数在SQLAlchemy 中创建了一个虚拟的列,它会和我们的 User 对象中的 db.ForeignKey 建立联系。
在此我在网络上找到一片文章讲解了——flask-sqlalchemy中 backref lazy的参数实例解释和选择