前言
为了配置好postgresql 和 flask的连接,我看了一个下午的文档和《export flask》,受益匪浅。还看了下sqlalchemy,既然用了postgresql ,ORM也要用上嘛,还用cursor 就太落伍了。
什么是Flask(name)
首先要搞清楚的是app = Flask(__name__)
,__name__
到底有什么作用。根据官方文档:
If you are using a single module (as in this example), you should use name because depending on if it’s started as application or imported as module the name will be different (‘main’ versus the actual import name). This is needed so that Flask knows where to look for templates, static files, and so on. For more information have a look at the Flask documentation.
About the First Parameter
The idea of the first parameter is to give Flask an idea of what belongs to your application. This name is used to find resources on the filesystem, can be used by extensions to improve debugging information and a lot more.
So it’s important what you provide there. If you are using a single module, name is always the correct value. If you however are using a package, it’s usually recommended to hardcode the name of your package there.
如果你的拉起服务的模块是单个模块(文件),直接写__name__
就好了,但是如果你要有static,template之类的,最好就是硬编码成Flask(你的包名),非常好理解的是,在python里有__init__.py
的文件夹就是包。
config的配置方法
配置的方法有两种,一种是通过在app.py中通过app.config[‘内置配置变量’]来配置,第二种是用额外的config文件来配置,额外的config文件可以有三种,一种是在根目录下的,一种是在instance目录下的,还有一种是在config目录下的。在根目录下的config.py和config目录下的一般为常用配置,在instance下的配置一般为设置api密钥的配置,一般是不随意更改的。
根据文档,配置可以写成类的形式。config目录下的config.py
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class Config(object):
"""Base config""" 基类,可以继承衍生出不同的开发环境的配置
DEBUG = False
DB_SERVER = 'localhost'
ENV = 'development'
@property
def DATABASE_URI(self):
return 'postgresql://flask_server:12345@{}/videocommunity'.format(self.DB_SERVER)
instance 目录下的配置
SECRET_KEY = ' |8\x07\xafX\xba\x1c\xd5\xb3\x94\xaamo&(\xb2)'
平时生成密钥可以用以下命令
python -c 'import os;print(os.urandom(16))'
配置生效
前面讲到有两种配置方法,通过app.config[‘内置配置变量’]来配置就是直接在app.py(拉起服务的文件)里面通过赋值来配置。如下,
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE_URL')
另一种也是在该文件中实现,但略有不同。
常用方法有
- app.config.from_object(‘包名.文件名’)
- app.config.from_envvar(‘环境变量名’)
- app.config.from_pyfile(‘文件名.py’,silent=True)
推荐使用类配置,根据文档给出示例,
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from config.default import Config
import os
app = Flask(__name__,instance_relative_config=True) 下文所指app
#instance里的config通常存放api密钥等不想让人知道的配置
app.config.from_object(Config())
#调用的是当前根目录下的config文件
#此时根目录下没有config文件就不需要这句
app.config['SQLALCHEMY_DATABASE_URI'] = Config.DATABASE_URI
#app.config.from_pyfile('config.py')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
#app.config['SQLALCHEMY_DATABASE_URI'] =
db = SQLAlchemy(app)
@app.route('/')
def hello():
return "Hello"
if __name__=='__main__':
app.run()
数据库迁移配置
依赖
迁移数据库必备依赖
sudo apt-fast install libpq-dev -y
sudo apt-fast install python-psycopg2 -y
pip install psycopg2
pip install Flask-SQLAlchemy Flask-Migrate flask_script
环境变量
之前打算避开使用环境变量的,但实践中发现迁移的时候一定要用到。
export DATABASE_URL=postgresql://用户名:密码@localhost/数据库名
例示:export DATABASE_URL=postgresql://flask_server:12345@localhost/videocommunity
env |grep DATABASE_URL
迁移
我也是学了postgresql才知道什么叫迁移,就是管理数据库版本,进行不同机器之间数据搬动就是数据库迁移。有了这个,在另外的开发环境就可以直接配置开发好的数据库了。
manager
数据库迁移需要用到一个Manager的模块,用上文提及的app为Manager注册,可以得到一个实例,用这个实例,可以进行数据库迁移。
在app.py中有一句db = SQLAlchemy(app)
,这个建立数据库连接。在manage.py中migrate = Migrate(app,db)
,这句代表着得到迁移实例。
贴出Models.py的代码
import sys
sys.path.append("..")
from app import db
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer,primary_key=True)
email = db.Column(db.String(64),unique=True,index=True)
username = db.Column(db.String(64),unique=True,index=True)
password_hash = db.Column(db.String(64))
def __init__(self,email,username,password_hash):
self.email = email
self.username = username
self.password_hash = password_hash
def __repr__(self):
return '<User %r>' % self.username
manage.py
import os
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
from config.default import Config
from myapp.models import User 这句最为重要,如果没有这句话,没有办法创建User这张表
from app import app, db
app.config.from_object(Config())
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE_URL')
migrate = Migrate(app,db)
manager = Manager(app)
manager.add_command('db',MigrateCommand)
if __name__ == '__main__':
manager.run()
迁移命令
python manage.py db init 初始化
python manage.py db migrate 迁移,但数据库中仍未变化
python manage.py db upgrade 执行完之后才有User这张表
如若需要新增表,更新迁移数据库
python manage.py db stamp head
python manage.py db migrate
python manage.py db upgrade
最好先检查信息
python manage.py db heads 检测目前版本
python manage.py db current -> 执行完stamp head 检查
目录结构
db-test/
├── __pycache__
│ └── app.cpython-37.pyc
├── app.py 服务器
├── config
│ ├── __init__.py
│ ├── __pycache__
│ └── default.py 常规配置(debug,DATABASE_URI)
├── instance 隐私配置文件(api密钥之类的)
│ └── config.py
├── manage.py 迁移脚本
├── migrations
│ ├── README
│ ├── __pycache__
│ ├── alembic.ini
│ ├── env.py
│ ├── script.py.mako
│ └── versions
├── myapp
│ ├── __init__.py
│ ├── __pycache__
│ └── models.py 数据库表
└── run.sh
参考
stack over-flow1
stack over-flow2
stack over-flow3
宫方文档
《explore flask》中文翻译
real-python