There is still a long way to go in the future. I think that as long as I keep exploring, innovation will not be just empty talk, I will go on step by step. You will find that our willpower is sometimes very good, and sometimes it is really bad, but we must continue to do what we decide to do and do well. Sometimes everyone just needs to record the process of their own growth, and when we are old, we can have a good aftertaste, we are all simple people, a long road, step by step.
Fortunately: We know what path we want to go next. Let us keep moving forward on the road of development.
flask项目实战 keep moving
- 常规配置:熟悉不同数据库如何配置
- 更多配置
配置名称 | 配置意义 |
---|---|
SQLALCHEMY_DATABASE_URI | 连接数据库的URI配置 |
SQLALCHEMY_BINDS | 一个字典,该字典通过绑定的key连接URI |
SQLALCHEMY_ECHO | 主要用于debug,为True的时候会回显数据库操作的原语 |
SQLALCHEMY_RECORD_QUERIES | 用于禁用或者启用查询记录。查询记录在调试或者测试模式会自动启用。 |
SQLALCHEMY_NATIVE_UNICODE | 用于禁用原生的unicode支持。 |
SQLALCHEMY_POOL_SIZE | 数据库连接池的大小,默认为5 |
SQLALCHEMY_POOL_TIMEOUT | 指定数据库连接池的连接超时时间 |
SQLALCHEMY_POOL_RECYCLE | 指定多久以后自动回收数据库 |
- sqlalchemy要对数据库进行映射,也需要对数据库的数据类型进行映射。映射后,sqlalchemy的主要字段类型可以参考下表。
字段类型名 | 对应的Python类型 | 字段说明 |
---|---|---|
Integer | int | 普通整数,一般是 32 位 |
SmallInteger | int | 取值范围小的整数,一般是 16 位 |
Big Integer | int 或 long | 不限制精度的整数 |
Float | float | 浮点数 |
Numeric | decimal.Decimal | 定点数 |
String | str | 变长字符串 |
Text | str | 变长字符串,对较长或不限长度的字符串做了优化 |
Unicode | unicode | 变长 Unicode 字符串 |
Unicode Text | unicode | 变长 Unicode 字符串,对较长或不限长度的字符串做了优化 |
Boolean | bool | 布尔值 |
Date | datetime.date | 日期 |
Time | datetime.time | 时间 |
DateTime | datetime.datetime | 日期和时间 |
Interval | datetime.timedelta | 时间间隔 |
Enum | str | 一组字符串 |
PickleType | 任何 Python 对象 | 自动使用 Pickle 序列化 |
LargeBinary | str | 二进制文件 |
- 对于不同的字段,可能还会有一些选项,比如该字段是否是主键,该字段的值是否允许重复,这些选项也被称为列选项。sqlalchemy的常见列选项见下表。
选项名称 | 选项说明 |
---|---|
primary_key | 如果设为 True,该列就是表的主键,注意:每个模型都应该有一个主键。一般会专门用一个名为id的字段来定义主键 |
unique | 如果设为 True,该列不允许出现重复的值 |
index | 如果设为 True,为该列创建索引,提升查询效率 |
nullable | 如果设为 True,该列允许使用空值;如果设为 False,这列不允许使用空值 |
default | 为该列定义默认值 |
- 导入SQLAlchemy
- 确认数据库配置完整
- 实例数据库链接对象
- 以db.Model为父类,构建数据库模型类
- 数据模型中的字段均是db.Colum类的实例,实例化传参的时候指定字段类型和选项
- 可以重载
__repr__
魔法方法,让模型对象有更好的可读性,不是必须实现的
python manager.py db init
需要注意,模型类是否能够在迁移过程中执行到,需要导包暴露出来
-
自动创建迁移脚本有两个函数
- upgrade():函数把迁移中的改动应用到数据库中。
- downgrade():函数则将改动删除。
-
自动创建的迁移脚本会根据模型定义和数据库当前状态的差异,生成upgrade()和downgrade()函数的内容。
-
对比不一定完全正确,有可能会遗漏一些细节,需要进行检查
python manager.py db migrate -m 'initial migration'
# 运行命令之后。可以看到migration文件夹中新增了数据库迁移的版本文件并没有在数据库也只是创建了版本号,并没有生成对应的表。
python manager.py db upgrade
迁移操作步骤
实际操作顺序:
1.python 文件 db init
2.python 文件 db migrate -m"版本名(注释)"
3.python 文件 db upgrade 然后观察表结构
4.根据需求修改模型
5.python 文件 db migrate -m"新版本名(注释)"
6.python 文件 db upgrade 然后观察表结构
7.若返回版本,则利用 python 文件 db history查看版本号
8.python 文件 db downgrade(upgrade) 版本号
app.config['HOST']="访问域名"
app.config.from_object(ProductionConfig)
HOST=localhost
export CONFIG_SET=./config.py
代码中使用from_envvar加载,底层使用的是from_pyfile
app.config.from_envvar('CONFIG_SET')
# `.env`
MAIL_PORT = 465
MAIL_USE_SSL = false
MAIL_USE_TLS = true
# settings.py
class BaseConfig(object):
...
MAIL_PORT = int(os.getenv('MAIL_PORT', default=587))
MAIL_USE_SSL = True if 'true' == os.getenv('MAIL_USE_SSL') else False
MAIL_USE_TLS = True if 'true' == os.getenv('MAIL_USE_TLS') else False
import os
from dotenv import load_dotenv
dotenv_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), '.env')
if os.path.exists(dotenv_path):
load_dotenv(dotenv_path, override=True) # override=True: 覆写已存在的变量
vim confile.py
HOST='locolhost'
...
app.config.from_pyfile('./confile.py') #加载配置文件
vim test.conf
[api] # section
port=8000 # option
import configparser
def getconfig(filename, section=''):
cf = configparser.ConfigParser() # 实例化
cf.read(filename) # 读取配置文件
cf_items = dict(cf.items(section)) if cf.has_section(
section) else {} # 判断SECTION是否存在,存在把数据存入字典,没有返回空字典
return cf_items
- 类似conf操作方式通过ConfigParser解析出相应的配置字典进行加载
- 什么是yaml文件?
- YAML是一种直观的能够被电脑识别的的数据序列化格式,容易被人类阅读,并且容易和脚本语言交互。YAML类似于XML,JSON等,但是语法简单得多,对于转化成数组或可以hash的数据时是很简单有效的。
# yaml格式
name: 张三
age: 37
children:
- name: 小明
age: 15
- name: 小红
age: 12
{
'name': '张三', 'age': 37,
'children': [{'name': '小明', 'age': 15}, {'name': '小红', 'age': 12}]
}
COMMON: &common
SECRET_KEY: insecure
DEBUG: False
DEVELOPMENT: &development
<<: *common
DEBUG: True
STAGING: &staging
<<: *common
SECRET_KEY: sortasecure
PRODUCTION: &production
<<: *common
SECRET_KEY: mdd1##$$%^!DSA#FDSF
import yaml
def read_yaml(yaml_file_path):
with open(yaml_file_path, 'rb') as f:
cf= f.read()
cf = yaml.load(cf)
return cf
from flask import Flask
app = Flask(__name__)
cf = read_yaml("setting.yaml")
app.config.update(cf)
from flask import Flask
import yaml
def read_yaml(yaml_file_path):
with open(yaml_file_path, 'rb') as f:
cf= yaml.safe_load(f.read()) # yaml.load(f.read())
return cf
app = Flask(__name__)
cf = read_yaml("setting.yaml")
app.config.update(cf)
if __name__ == "__main__":
app.run()
import os
import json
from flask import Flask
def create_app():
app = Flask('test')
# 这里在虚拟环境中设置环境变量。 export RMON_CONFIG=xxx.json
file = os.environ.get('RMON_CONFIG')
content = ''
if file:
rest = {}
with open(file) as f:
for line in f:
# if line.strip().startswith('#'):
if "#" in line:
continue
content += line
if content:
config = json.loads(content)
for k in config:
app.config[k.upper()] = config[k]
return app
if __name__ == '__main__':
create_app()