一、背景
利用flask+mysql+mongodb开发一个网站,对文件结构以及将已存在的数据表用SQLALchemy转成操作对象,并对flask文件结构进行组织。
二、文件组织架构
我按照MVC的模式设计我的文件结构,flask和Django属于MVT的结构,这里T用前后端分离的方式来实现,所以文件的结构模型如下图。
2.1 文件结构模型
2.2 文件结构
三、连接数据库
按照相应的驱动包
# mysql
pip install sqlalchemy
# mongo
pip install Flask-PyMongo
3.1 写好文件配置
写好相应的配置,使用sqlalchemy_database_uri进行连接。mongodb或者sqlite也是一样,mongo配置参考文件。
# mysql连接管理
from flask_sqlalchemy import SQLAlchemy
# 导入相应的配置
from webLearn.dbconfig.db_config import *
DIALECT = 'mysql'
DRIVER = 'pymysql'
USERNAME = MYSQL_NAME
PASSWORD = MYSQL_PASSWORD
HOST = MYSQL_HOST
PORT = MYSQL_PORT
DATABASE = MYSQL_DB
SQLALCHEMY_DATABASE_URI = '{}+{}://{}:{}@{}:{}/{}?charset=utf8'.format(
DIALECT, DRIVER, USERNAME, PASSWORD, HOST, PORT, DATABASE
)
# 自动提交变动
SQLALCHEMY_COMMIT_ON_TEARDOWN = True
# 追踪对象修改,部署的时候可以设置成False
SQLALCHEMY_TRACK_MODIFICATIONS = True
# 初始化db,在这里声明防止循环导入
db = SQLAlchemy()
3.2 在flask的APP注册
# 注册mysql的配置并初始化
# 注册方式有多种方式,使用py文件或者是使用对象或者环境都可以
app.config.from_pyfile('./dbconfig/mysql_manage.py')
db.init_app(app)
# 注册mongo的配置并初始化
app.config.from_pyfile('./dbconfig/mongo_manage.py')
mongo.init_app(app)
四、现有数据表转化
flask使用的是使用orm映射,可以使用现有的数据进行设计,然后使用create_all()进行创建,也可以通过sqlacodegen反向建立数据表,操作入下:
# 安装指令
pip install sqlacodegen
使用命令导出SQLAlchemy,然后就可以对其进行操作,如果不输出文件名就会在控制台打印,注:有中文这样子导出来有乱码。
# 指令
# []:参数类型
# {}:可选参数
sqlacodegen mysql+pymysql://[连接名]:[密码]@[ip]/[db_name] {{--tables [表名]}>[输出名字].py}
五、使用路由进行查询
5.1 引入model
我们在view中引入model进行数据查询,获取相应的数据。
# 用户管理页面访问
import json
from flask import Blueprint, request, jsonify
# 引入model
from webLearn.model.user import User
# 蓝图注册
user = Blueprint("user", __name__)
5.2 查询方式
我们可以通过db对象进行查询,也可以使用model生成的管理对象进行查询(Base查询)。
@user.route('/login', methods=['GET', 'POST'])
def login_method():
param = request.json
userid = param.get("id")
password = param.get("password")
result = User.query.filter(User.id == userid, User.password == password).all()
data = {}
if result:
data.update({'code': 200})
return jsonify(data)
data.update({"code": -1})
return jsonify(data)
5.3 数据优化
我们查询的结果是一个对象,这个时候就需要涉及对这个对象进行序列化的问题,我们需要在model文件中去设计一个json化的方法。
def to_json(self):
"""将实例对象转化为json"""
item = self.__dict__
# 这个是用于session存储的内容,可以通过print(item)来查看
if "_sa_instance_state" in item:
del item["_sa_instance_state"]
# 涉及时间数据的转化,可能还有优化的地方。
if 'birthday' in item:
item['birthday'] = self.birthday.strftime("%Y-%m-%d")
return item
六、注意
6.1 问题
在引入配置的时候,会出现import错误,这是因为循环引入的原因。我们需要在view中引入model,在app中引入view(蓝图),在model中引入app进行注册,这个时候就会出现循环引入的问题。
6.2 解决方案
我们建立一个新文件,用于生成mysql或者其他数据库的连接对象,然后在去引入这个文件。我的做法将数据库对象放入到对应的管理文件中,这样在model,app中都引入这个文件,就不存在循环引用。
七、参考
其他人的blog:
官方文档: