头图:https://cdn.naraku.cn/imgs/flask-0.jpg
摘要:简单学了一点Flask基础,记录一下。
Flask基础
- 传值总结:https://blog.csdn.net/MooKee_cc/article/details/52947332
命令行启动
$ flask run --port=8080
运行过程
- 客户端向服务器发起请求
- 服务器把请求交给Flask实例
- Flask实例通过
Werkzeug根据URL请求与视图函数之间的对应关系来进行路由分发 - 根据每个URL请求,找到具体的视图函数并进行调用
- Flask程序中路由一般是通过程序实例的装饰器实现
- Flask调用视图函数后,可以返回2种内容:
- 新建一个Flask项目
导入Flask类
# 导入Flaskfrom flask import Flask
创建实例。需要传入一个参数
name,指向程序所在的模块app = Flask(__name__)
配置路由。通过装饰器将路由映射到视图函数
@app.route('/')def index():return 'Hello World!'
完整代码 ```python
-- coding:utf-8 --
导入Flask
from flask import Flask
创建实例
app = Flask(name)
路由与视图函数对应关系
@app.route(‘/‘) def index(): return ‘Hello World!’
启动程序
if name == ‘main‘: app.run()
<a name="75fc7de7"></a>## 路由<a name="3b4c5cab"></a>### 请求方式- 使用`methods`参数指定可接受的请求方式,可指定多种,默认只接受`GET`请求```python@app.route('/', methods=['GET','POST'])def hello():return 'Hello'
参数处理
有时候需要将同一类URL映射到同一个视图函数处理,例如某个分类下不同的图书返回不同信息
- 使用
<>定义路由动态参数 - 并且将该参数传入视图函数
@app.route('/code/<book_id>')def book(book_id):print(type(book_id)) # 默认是strreturn f'当前书本ID为: {book_id}'
- 使用
有时候需要对路由做访问优化。例如上面的
book_id应是int类型- 只需要在
<>中的变量名前加上指定类型:即可 - 若指定为
int类型,则访问/code/abc等str类型的路由时会返回404 Not Found@app.route('/code/<int:book_id>')def book(book_id):print(type(book_id)) # 此时为intreturn f'当前书本ID为: {book_id}'
- 只需要在
模板引擎
视图函数的作用有2个:处理业务逻辑和内容。
- 模板其实是一个包含响应文本的文件,用变量表示动态部分,告诉模板引擎其具体的值需要从使用的数据中获取
- 使用真实值替换变量,再返回最终的字符串,这个过程称为渲染。Flask使用模板引擎
Jinja2来渲染模板
返回HTML
- 前面都是写如何返回字符串,那么如果需要返回HTML模板,则可以通过
render_template实现
app = Flask(name)
@app.route(‘/‘) def index(): return render_template(‘index.html’) # templates目录下的index.html
if name == ‘main‘: app.run()
<a name="457a9254"></a>### 动态渲染- 如果需要在模板中使用某些动态的参数,则需要在视图函数中传递参数- 视图函数中通过`render_template()`函数传参- HTML模板文件中通过`{{}}`使用该变量```python@app.route('/')def index():url = "www.naraku.cn"return render_template('index.html', url=url)
index.html:<h1>欢迎来到: {{ url }}</h1>
用法
注释:
{# #}{# 这是注释 #}{# {{name}} #}
控制:
{% %}```html {% if id>50 %} {{id}} => 大于50 {% elif id<50 %} {{id}} => 小于50 {% else %} {{id}} => 等于50 {% endif %}
{% for num in nums %}
当前数字为: {{num}}
{% endfor %}
- 举个例子```pythondef index():id = 100nums = [1, 2, 3, 4, 5]return render_template('index.html', id=id, nums=nums)
index.html
{% if id>50 %}<h1>id为: {{id}} => 大于50</h1>{% elif id<50 %}<h1>id为: {{id}} => 小于50</h1>{% else %}<h1>id为: {{id}} => 等于50</h1>{% endif %}{# 注释: 上面是if,下面是for #}{% for num in nums %}<p>当前数字为: {{num}}</p>{% endfor %}
过滤器
- 过滤器的本质是函数,有时候不仅仅只是需要输出变量的值,还需要修改变量的显示,甚至格式化、运算等等,而在模板中是不能直接调用Python中某些方法的,那么就用到了过滤器
使用方式:
过滤器的使用方式:
变量名 | 过滤器{{ name | filter(*args) }}
如果没有任何参数传给过滤器,可以省略括号
{{ name | filter }}
举个例子
@app.route('/')def index():name = "naraku"return render_template('index.html', name=name)
{# 字符串变大写 #}<p>{{ name | upper }}</p>
链式调用
Jinja2中,过滤器支持链式调用,从左到右按顺序执行
<p>{{ 'Hello World' | upper | reverse }}</p>
常用过滤器
format:格式化输出<p>{{ '%s' | format(name) }}</p>
safe:禁用转义<p>{{ '<em>hello</em>' | safe }}</p>
capitalize:首字母大写,其余小写<p>{{ 'hello' | capitalize }}</p>
upper/lower:全部转为大写或小写 ```html{{ ‘Hello World’ | lower }}
{{ ‘Hello World’ | upper }}
- `reverse`:字符串反转```html<p>{{ 'Hello World' | reverse }}</p>
truncate:字符串截断<p>{{ 'hello world' | truncate(3) }}</p>
striptags:渲染前把所有HTML标签删除<p>{{ '<em>hello</em>' | striptags }}</p>
Web表单
Web表单是Web程序的基本功能,它是HTML页面中负责数据采集的部件。表单中有三部分组成:表单标签、表单域、表单按钮。表单允许用户输入数据,负责HTML页面数据采集,通过表单将用户输入的数据提交给服务器。
简单示例
视图函数
路由需要有
GET和POST请求,需要判断请求方式- 路由中添加参数
methods,以列表的方式传入请求方式GET和POST 引入
request对象,获取请求方式及参数@app.route("/", methods=['GET', 'POST'])def index():# 获取请求方式if request.method == "POST":# 获取请求参数username = request.form.get('username')password = request.form.get('password')password2 = request.form.get('password2')# 判断参数是否完整if not all([username, password, password2]):print("参数不完整")elif password != password2:print("密码不一致")else:return "success"return render_template("index.html")
- 路由中添加参数
模板文件
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>WTF</title></head><body><form method="post"><label>用户名:</label><input type="text" name="username"><br><label>密码:</label><input type="password" name="password"><br><label>确认密码:</label><input type="password" name="password2"><br><input type="submit" value="提交"><br></form></body></html>
Flash消息闪现
- 有时候需要向模板动态传递一些消息,例如提示用户名不能为空、密码不一致等等,可以通过
flash库实现- 引入
flash库 - 设置密钥
Secret_key```python from flask import Flask, render_template, request, flash
- 引入
app = Flask(name)
@app.route(“/“, methods=[‘GET’, ‘POST’]) def index(): if request.method == “POST”: username = request.form.get(‘username’) password = request.form.get(‘password’) password2 = request.form.get(‘password2’)
# 向模板传递消息if not all([username, password, password2]):flash("参数不完整")elif password != password2:flash("密码不一致")else:return "success"return render_template("index.html")
if name == ‘main‘: app.run()
- 模板文件通过`get_flashed_messages()`函数获取消息并渲染```html<body><form method="post"><label>用户名:</label><input type="text" name="username"><br><label>密码:</label><input type="password" name="password"><br><label>确认密码:</label><input type="password" name="password2"><br><input type="submit" value="提交"><br>{# 通过遍历函数获取消息 #}{% for msg in get_flashed_messages() %}{{ msg }}{% endfor %}</form></body>
- 此时直接启动程序,会出现报错,原因是因为未设置密钥
Secret_key

flash希望对需要输出的内容进行加密,因此需要设置密钥,作加密消息的混淆。- 只需要一行代码,给
app.secret_key赋值即可 ```python from flask import Flask, render_template, request, flash
- 只需要一行代码,给
app = Flask(name) app.secret_key = “naraku” # 设置密钥
….
- 如果使用**Python2**进行开发,可能会遇到`UnicodeDecodeError`等编码的问题,只需要在中文字符前面加个`u`进行转码即可```python@app.route("/", methods=['GET', 'POST'])def index():if request.method == "POST":username = request.form.get('username')password = request.form.get('password')password2 = request.form.get('password2')# 向模板传递消息if not all([username, password, password2]):flash(u"参数不完整") # 这里加个uelif password != password2:flash(u"密码不一致")else:return "success"return render_template("index.html")
过滤
- 有时需要在不同的地方显示不同信息
flash()接收2个参数,通过指定第2个参数category,并在前端通过category_filter=["分类名"]过滤调用if open_form.submit.data and open_form.validate_on_submit():pill_key = request.form.get('pill_key')flash(f"Open表单提交成功: {pill_key}", category="open")elif find_form.submit.data and find_form.validate_on_submit():find_email = request.form.get('find_email')flash(f"Find表单提交成功: {find_email}", category="find")
{% for msg in get_flashed_messages(category_filter=["find"]) %}{{ msg }} <br>{% endfor %}
插件-表单-WTF
在Flask中,为了处理Web表单,一般使用Flask-WTF扩展,它封装了WTForms,并且验证表单数据的功能。
- 使用
Flask-WTF需要配置密钥参数SECRET_KEY,必须开启**CSRF_token** CSRF_ENABLED可以防止CSRF,SECRET_KEY用于生成加密令牌。CSRF防护会根据设置的密钥生成加密令牌- 需要先安装此插件
pip install Flask-WTF
基本示例
- 先自定义一个表单类
- 继承自基类
FlaskForm - 导入所需的表单字段 ```python from flask_wtf import FlaskForm from wtforms import StringField, PasswordField, SubmitField
- 继承自基类
app = Flask(name) app.secret_key = “naraku”
class RegForm(FlaskForm): username = StringField(“账号:”) password = PasswordField(“密码:”) password2 = PasswordField(“确认密码:”) submit = SubmitField(“提交”)
- 传递到模板```python@app.route("/reg", methods=['GET', 'POST'])def reg():reg_form = RegForm()return render_template("index.html", reg_form=reg_form)
前端渲染
<body><form method="post">{{ reg_form.username.label }} {{ reg_form.username }} <br>{{ reg_form.password.label }} {{ reg_form.password }} <br>{{ reg_form.password2.label }} {{ reg_form.password2 }} <br>{{ reg_form.submit }}</form></body>
完整代码 ```python
-- coding:utf-8 --
from flask import Flask, render_template, request, flash from flask_wtf import FlaskForm from wtforms import StringField, PasswordField, SubmitField
app = Flask(name) app.secret_key = “naraku”
class RegForm(FlaskForm): username = StringField(“账号:”) password = PasswordField(“密码:”) password2 = PasswordField(“确认密码:”) submit = SubmitField(“提交”)
@app.route(“/reg”, methods=[‘GET’, ‘POST’]) def reg(): reg_form = RegForm() return render_template(“index.html”, reg_form=reg_form)
if name == ‘main‘: app.run()
<a name="6cc7dc63"></a>### 表单验证- 引入验证函数,并在表单类中实现- **必须开启**`**CSRF_token**`,否则验证失败- 通过`validators`传递需要调用的函数,可以为一个列表- `DataRequired()`,判断字段是否非空- `EqualTo()`,判断当前字段与目标字段是否相等。第1个参数为目标字段,第2个参数为错误消息```pythonfrom wtforms.validators import DataRequired, EqualToclass RegForm(FlaskForm):username = StringField("账号:", validators=[DataRequired()])password = PasswordField("密码:", validators=[DataRequired()])password2 = PasswordField("确认密码:", validators=[DataRequired(), EqualTo("password", "密码不一致")])submit = SubmitField("提交")
表单验证
- 通过
表单对象.validate_on_submit()函数一行实现表单验证 ```python @app.route(“/reg”, methods=[‘GET’, ‘POST’]) def reg(): reg_form = RegForm() # 创建一个表单对象
获取请求方式
if request.method == “POST”:
获取请求参数
username = request.form.get(‘username’) password = request.form.get(‘password’) password2 = request.form.get(‘password2’)
表单验证
if reg_form.validate_on_submit():
return "Success"
else:
pass
return render_template(“index.html”, reg_form=reg_form) ```
- 通过
前端开启
CSRF_token通过调用
对象名.csrf_token()函数开启<body><form method="post">{# 开启CSRF_token #}{{ reg_form.csrf_token() }}{{ reg_form.username.label }} {{ reg_form.username }} <br>{{ reg_form.password.label }} {{ reg_form.password }} <br>{{ reg_form.password2.label }} {{ reg_form.password2 }} <br>{{ reg_form.submit }}<br>{# Flash消息 #}{% for msg in get_flashed_messages() %}{{ msg }}{% endfor %}</form></body>
完整代码 ```python
-- coding:utf-8 --
from flask import Flask, render_template, request, flash from flask_wtf import FlaskForm from wtforms import StringField, PasswordField, SubmitField from wtforms.validators import DataRequired, EqualTo
app = Flask(name) app.secret_key = “naraku”
class RegForm(FlaskForm): username = StringField(“账号:”, validators=[DataRequired()]) password = PasswordField(“密码:”, validators=[DataRequired()]) password2 = PasswordField(“确认密码:”, validators=[DataRequired(), EqualTo(“password”, “密码不一致”)]) submit = SubmitField(“提交”)
@app.route(“/reg”, methods=[‘GET’, ‘POST’]) def reg(): reg_form = RegForm()
# 获取请求方式if request.method == "POST":# 获取请求参数username = request.form.get('username')password = request.form.get('password')password2 = request.form.get('password2')# 表单验证if reg_form.validate_on_submit():return "success"else:flash("参数有误")return render_template("index.html", reg_form=reg_form)if __name__ == '__main__':app.run(debug=True)
<a name="1936afac"></a>### 常用字段| 字段对象 | 说明 || --- | --- || StringField | 文本字段 || TextAreaField | 多行文本字段 || PasswordField | 密码字段 || HiddenField | 隐藏文件字段 || DateField | 文本字段,值为 `datetime.date`<br /> 文本格式 || DateTimeField | 文本字段,值为 `datetime.datetime`<br /> 文本格式 || IntegerField | 文本字段,值为整数 || DecimalField | 文本字段,值为`decimal.Decimal` || FloatField | 文本字段,值为浮点数 || BooleadnField | 复选框,`True`<br />/`False` |<a name="6114e108"></a>### 常用验证函数| 验证函数 | 说明 || --- | --- || `DataRequired` | 确保字段中有数据 || `EqualTo` | 比较两个字段的值,常用于判断两次密码是否一致 || `Length` | 验证输入的字符串长度 || `NumberRange` | 验证输入的数值范围 || `URL` | 验证URL || `AnyOf` | 验证输入值在可选列表中 || `NoneOf` | 验证输入值不在可选列表中 |<a name="cc09f939"></a>## 插件-数据库-SQLAlchemy- `SQLAlchemy`是一个关系型数据库框架,它提供了高层ORM和底层的原生数据库操作,`Flask-sqlalchemy`是一个简化了的`SQLAlchemy`操作的扩展。`SQLAchemy`实际上是对数据库的抽象,让开发者不用直接和SQL语句打交道,而是通过Python对象来操作数据库。- 安装`Flask-sqlalchemy````shellpip install flask-sqlalchemy
- 如果需要操作Mysql,还需要安装
mysqldbpip install flask-mysqldb
管理数据库
在
Flask-SQLAlchemy中,数据库使用URL指定,而且程序使用的数据库必须保存到Flask配置对象的SQLALCHEMY_DATABASE_URI键中数据库类型://数据库账号:密码@地址:端口/数据库名app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:root@127.0.0.1:3306/flask'
其它设置
# 动态追踪修改设置,如未设置只会提示警告,不建议开启app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
创建数据库对象
- 引入相关库,配置app对象的数据库信息,创建数据库对象,并传入当前app对象 ```python from flask import Flask from flask_sqlalchemy import SQLAlchemy
app = Flask(name) app.config[‘SQLALCHEMY_DATABASE_URI’] = ‘mysql://root:root@127.0.0.1:3306/flask_demo’ app.config[‘SQLALCHEMY_TRACK_MODIFICATIONS’] = False db = SQLAlchemy(app)
- 创建一个数据库,打开命令行登录数据库后输入```sqlcreate database flask_demo charset=utf8;
数据模型
- 定义数据模型
| Roles表 | |
| —- | —- |
|
role_id(
主键) | | | 1 | 管理员 | | 2 | 普通用户 |
| Users表 | ||
|---|---|---|
user_id |
user_name |
role_id(外键) |
| 1 | 1号管理 | 1 |
| 2 | 2号管理 | 1 |
| 3 | 用户A | 2 |
- 实现数据模型
class User(db.Model): tablename = ‘users’ id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(16), unique=True) role_id = db.Column(db.Integer, db.ForeignKey(‘roles.id’)) # 外键
- 创建表```pythonif __name__ == '__main__':# db.drop_all() # 删除表db.create_all() # 新建表# app.run()

基本操作
- 增删改操作,由数据库会话
db.session管理- 在准备把数据写入数据库前,要先将数据添加到会话中,然后调用
db.session.commit()方法提交会话
- 在准备把数据写入数据库前,要先将数据添加到会话中,然后调用
- 查询操作,通过
query对象进行操作- 最基本的查询是返回表中所有数据,可以通过过滤器进行更精确的数据库查询
增删改
if __name__ == '__main__':# db.drop_all() # 删除表# db.create_all() # 新建表# 增加# Role表增加用户role = Role(name='admin') # 创建一个对象db.session.add(role) # 将添加对象加入会话db.session.commit() # 将会话提交到数据库# User表增加用户# 此时role对象的id为1,所以创建的user是管理员权限user = User(name='naraku', role_id=role.id)db.session.add(user)db.session.commit()# app.run()# 修改# 前面已经把user对象添加到db.session()中,因此不需要再次添加user.name = 'miroku'db.session.commit()# 删除db.session.delete(user)db.session.commit()

- 其它语句
db.session.add(role) # 添加到数据库的session中db.session.add_all([user1, user2]) # 以列表形式添加多个db.session.rollback() # 回滚操作db.session.delete(user) # 删除数据db.session.commit() # 提交到数据库
查询
简单应用
from flask import Flask from flask_sqlalchemy import SQLAlchemy
app = Flask(name) app.config[‘SQLALCHEMY_DATABASE_URI’] = ‘mysql://root:root@127.0.0.1:3306/flask_demo’ app.config[‘SQLALCHEMY_TRACK_MODIFICATIONS’] = False db = SQLAlchemy(app)
class Role(db.Model): tablename = ‘roles’ id = db.Column(db.Integer, primary_key=True) # 主键 name = db.Column(db.String(16), unique=True) # 唯一 users = db.relationship(‘User’, backref=’role’)
class User(db.Model): tablename = ‘users’ id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(16), unique=True) email = db.Column(db.String(16), unique=True) role_id = db.Column(db.Integer, db.ForeignKey(‘roles.id’)) # 外键
def __repr__(self):return f'<User: {self.id}, {self.name}, {self.email}>'
@app.route(‘/‘) def index(): return ‘Hello SQLAlchemy’
if name == ‘main‘: db.drop_all() # 删除表 db.create_all() # 新建表
Role表
role1 = Role(name='Admin') # 管理员role2 = Role(name='Guest') # 普通用户db.session.add_all([role1, role2])db.session.commit()# User表user1 = User(name='naraku',email='naraku@qq.com' , role_id=role1.id)user2 = User(name='zhang',email='zhang@qq.com' , role_id=role2.id)user3 = User(name='chen',email='chen@qq.com' , role_id=role2.id)user4 = User(name='zhou',email='zhou@qq.com' , role_id=role2.id)user5 = User(name='tang',email='tang@qq.com' , role_id=role2.id)user6 = User(name='wu',email='wu@qq.com' , role_id=role2.id)user7 = User(name='qian',email='qian@qq.com' , role_id=role2.id)user8 = User(name='liu',email='liu@qq.com' , role_id=role2.id)user9 = User(name='li',email='li@qq.com' , role_id=role2.id)user10 = User(name='sun',email='sun@qq.com' , role_id=role2.id)db.session.add_all([user1, user2, user3, user4, user5, user6, user7, user8, user9, user10])db.session.commit()
- 这里借助`ipython`这个库,可以直接在`Pycharm`下方的`Terminal`终端调用进行查询。如果没有`ipython`的可通过`File-> setting-> Project Interpreter`进行安装- 安装完成后在`Terminal`输入`ipython`进入,并导入当前文件全部代码```shell> ipythonIN [1]: from demo import *

查询id为4的用户
因为id是主键,可通过执行器get查询
User.query.get(4)
通过过滤器查询
User.query.filter_by(id=4).first() User.query.filter(User.id==4).first()
<a name="cc525323"></a>##### 查询执行器`表模型名.query.方法()`| 方法 | 说明 || --- | --- || `all()` | 以列表形式返回查询的所有结果 || `first()` | 返回查询的第一个结果,如未查到,返回None || `first_or_404()` | 返回查询的第一个结果,如未查到,返回404 || `get()` | 返回指定主键对应的行,如不存在,返回None || `get_or_404()` | 返回指定主键对应的行,如不存在,返回404 || `count()` | 返回查询结果的数量 || `paginate()` | 返回一个Paginate对象,它包含指定范围内的结果 |<a name="333bd245"></a>##### 查询过滤器| 过滤器 | 说明 || --- | --- || `filter(对象.属性==值)` | 把过滤器添加到原查询上,返回一个新查询。支持比较运算符 || `filter_by(属性=值)` | 把等值过滤器添加到原查询上,返回一个新查询 || `limit` | 使用指定的值限定查询返回结果 || `offset()` | 偏移原查询返回的结果 || `order_by()` | 根据指定条件对原查询进行排序,返回一个新查询 || `group_by()` | 根据指定条件对原查询进行分组,返回一个新查询 |<a name="69851aa1"></a>### 关系引用有时候需要一些属性方便查询数据,但是这些属性不能出现在数据库的字段中- `relationship()`:`sqlalchemy`对关系之间提供的一种便利的调用方式,关联不同的表- 第1个参数:对象模型名。指需要关联的对象,可在`Role`类的实例中通过`role.users`查看该实例在`User`模型中的属性- `backref`参数:对关系提供**反向引用**的声明。可在`User`类的实例中通过`user.role`查看该实例在`Role`模型中的属性```pythonclass Role(db.Model):__tablename__ = 'roles'id = db.Column(db.Integer, primary_key=True) # 主键name = db.Column(db.String(16), unique=True) # 唯一# 关键代码users = db.relationship('User', backref='role')class User(db.Model):__tablename__ = 'users'id = db.Column(db.Integer, primary_key=True)name = db.Column(db.String(16), unique=True)role_id = db.Column(db.Integer, db.ForeignKey('roles.id')) # 外键
- 完整代码
__repr__(self):输出某个实例化对象时的回显 ```python from flask import Flask from flask_sqlalchemy import SQLAlchemy
app = Flask(name) app.config[‘SQLALCHEMY_DATABASE_URI’] = ‘mysql://root:root@127.0.0.1:3306/flask_demo’ app.config[‘SQLALCHEMY_TRACK_MODIFICATIONS’] = False db = SQLAlchemy(app)
class Role(db.Model): tablename = ‘roles’ id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(16), unique=True)
# 关键代码users = db.relationship('User', backref='role')def __repr__(self):return f'<Role: {self.name}, {self.id}>'
class User(db.Model):
tablename = ‘users’
id = db.Column(db.Integer, primarykey=True)
name = db.Column(db.String(16), unique=True)
roleid = db.Column(db.Integer, db.ForeignKey(‘roles.id’)) # 外键
def __repr(self):
return f’
@app.route(‘/‘) def index(): return ‘Hello SQLAlchemy’
if name == ‘main‘: db.drop_all() # 删除表,防止测试时数据冗余 db.create_all() # 新建表 role = Role(name=’admin’) db.session.add(role) db.session.commit()
user1 = User(name='naraku', role_id=role.id)user2 = User(name='miroku', role_id=role.id)db.session.add_all([user1, user2])db.session.commit()print(role.users) # 查看Role实例在User表中的属性print(user1.role) # 查看User实例在Role表中的属性print(user2.role)
<a name="0613b887"></a>### 常见字段- `db.字段名`| 类型名 | Python数据类型 | 说明 || --- | --- | --- || `Integet` | `int` | 普通整数,一般是32位 || `SmallInteget` | `int` | 取值范围小的整数,一般是16位 || `BigInteget` | `int/long` | 不限制精度的 || `Float` | `float` | 浮点数 || `Numeric` | `decimal.Decimal` | 普通整数,一般是32位 || `String` | `str` | 变长字符串 || `Text` | `str` | 变长字符串,对较长或不限长度的字符串做了优化 || `Unicode` | `unicode` | 变长Unicode字符串 || `UnicodeText` | `unicode` | 变长Unicode字符串,对较长或不限长度的字符串做了优化 || `Boolean` | `bool` | 布尔值 || `Date` | `datetime.date` | 时间 || `Time` | `datetime.datetime` | 日期和时间 || `LargeBinary` | `str` | 二进制文件 |<a name="b043fc3a"></a>### 常见列选项| 选项名 | 说明 || --- | --- || `primary_key` | 主键。若为`True`<br />,即为表的主键 || `unique` | 唯一。若为`True`<br />,即此列不允许出现重复的值 || `default` | 默认值。为此列定义默认值 || `index` | 索引。若为`True`<br />,为此列创建索引,提高查询效率 || `nullable` | 非空。若为`True`<br />,允许为空,反之不允许为空 |<a name="a8d14911"></a>## 依赖包```shell$ pip freeze > requirements.txt # 输出依赖包及版本到文本$ pip install -r requirements.txt # 安装依赖包
