赞
踩
|-- application.py # flask中的全局变量,包括APP,数据库等 |-- common # 相当于utils,存放公共部分 | |-- __init__.py | |-- libs # 公共方法或者类 | |-- models # MVC中的models层 |-- config # 配置文件 | |-- base_setting.py # 基础设置 | |-- __init__.py | |-- local_setting.py # 本地开发环境 | `-- production_setting.py # 生产环境 |-- docs # 文档存放部分 | `-- mysql.md # 所有数据库变更记录 |-- jobs # 定时任务 | |-- bash_jobs # 脚本文件 | |-- __init__.py | |-- launcher.py # 自定义命令行启动 | |-- readme.md | `-- tasks # 定时任务 |-- manager.py # 启动入口 |-- readme.md |-- requirements.txt # 后端所需包 |-- uwsgi.ini # 部署配置文件 |-- web # 交互 | |-- controllers # MVC中的C,控制器部分 | |-- __init__.py | |-- interceptors # 拦截器部分 | |-- static # 静态文件 | `-- templates # 模板文件 `-- www.py # HTTP模块相关初始化
创建虚拟环境安装如下包:
flask
flask-sqlalchemy
flask-debugtoolbar
mysqlclient
flask_script
requests
uwsgi
这里因为课程都是用flask-sqlacodegen反迁移的方式分别插入到相应的models文件中,相应命令为:
flask-sqlacodegen 'mysql://root:123456@127.0.0.1/food_db' --outfile "common/models/model.py" --flask
flask-sqlacodegen 'mysql://root:123456@127.0.0.1/food_db' --tables user --outfile "common/models/user.py" --flask
虽然看起来是没什么问题的,后续也就每个models文件都执行一次上面的命令,我认为如果按作者的逻辑顺序,我们首先创建好food_db数据库,编码为utf8mb4,然后我们导入他在数据库文件中的food.sql,source一下创建好所有的表:
然后我们show tables就能看到所有的表:
Query OK, 0 rows affected, 7 warnings (0.10 sec) mysql> show tables; +-------------------------+ | Tables_in_food_db | +-------------------------+ | app_access_log | | app_error_log | | food | | food_cat | | food_sale_change_log | | food_stock_change_log | | images | | member | | member_address | | member_cart | | member_comments | | oauth_access_token | | oauth_member_bind | | pay_order | | pay_order_callback_data | | pay_order_item | | queue_list | | stat_daily_food | | stat_daily_member | | stat_daily_site | | user | | wx_share_history | +-------------------------+ 22 rows in set (0.03 sec)
我们再依次对上述命令针对于每个models下的模块进行反迁移,我感觉这样其实也可以,如果是将所有models写进一个文件中,但按本项目中的架构就显得有点矛盾,在没有models代码的情况下,我们需要运行flask-sqlacodegen近20次才能保证所有文件都要模型类。
那么,上面的操作都是反向迁移,数据库已经提前写好了。但若是我们希望能正向迁移,那应该怎么做呢?
第一种方式我觉得能写一个文件将所有models文件连接起来,然后利用flask-migrate,对migrations中的env指向我们做好的文件中,这种我感觉理论上是行得通的,因为类似django的机制。但工作量会比较大,其次就是不符合flask的初衷,所以能用第二种方式,就是使用 db.create_all()函数,让 SQLAlchemy 根据模型类创建数据库。
将local_settings中数据库配置复制一份在application中直接引用:
app = Application( __name__,template_folder=os.getcwd() + "/web/templates/",root_path=os.getcwd())
app.config["SQLALCHEMY_DATABASE_URI"] = 'mysql://root:password@IP:prot/food_db?charset=utf8mb4'
然后在该文件所在文件目录下,打开终端,然后进入到 Python 命令行,你也可以用 python manager.py shell 这个命令。
>> from application import db
>> db.create_all()
然后就可以看见如下的sql语句:
2019-12-09 16:02:28,286 INFO sqlalchemy.engine.base.Engine ()
2019-12-09 16:02:28,400 INFO sqlalchemy.engine.base.Engine COMMIT
2019-12-09 16:02:28,437 INFO sqlalchemy.engine.base.Engine
CREATE TABLE wx_share_history (
id INTEGER NOT NULL AUTO_INCREMENT,
member_id INTEGER NOT NULL,
share_url VARCHAR(200) NOT NULL,
created_time DATETIME NOT NULL,
PRIMARY KEY (id)
)
所有用户表总结:
主要是一些配置文件以及前期准备工作。
# _*_ coding:utf-8 _*_ from flask import Flask from flask_script import Manager from flask_sqlalchemy import SQLAlchemy from common.libs.UrlManager import UrlManager import os class Applicaltion(Flask): def __init__(self,import_name,template_folder=None,root_path=None): # 在自定义结构项目中要改变template、static默认的设置路径 super(Applicaltion,self).__init__(import_name,template_folder=template_folder,root_path=root_path,static_folder=None) if "ops_config" in os.environ: print(os.environ["ops_config"]) # 获取环境变量的值 # 根据环境变量改变配置文件 self.config.from_pyfile('config/%s_setting.py'%os.environ["ops_config"],silent=True) db.init_app(self) db = SQLAlchemy() # root_path=os.getcwd() 设置默认的根目录路径 app = Applicaltion(__name__,template_folder=os.getcwd()+'/web/templates',root_path=os.getcwd()) manager = Manager(app) ''' 函数模板:把python方法注入到模板引擎中 ''' app.add_template_global(UrlManager.buildStaticUrl,'buildStaticUrl') app.add_template_global(UrlManager.buildUrl,'buildUrl')
这里会出现一个问题,因为我们改变了静态文件所在的地址,没有用template目录,前面我们已经通过os模块将模板的路径地址进行了调整,而static_folder我们设置的是None,所以我们可以在本地环境下新建一个static.py的文件来管理静态文件;默认的静态目录是项目目录下直接的static,跟模板目录一样,需要重新设置加载路径。
# _*_ coding:utf-8 _*_ from flask import Blueprint,send_from_directory from application import app route_static = Blueprint('static',__name__) @route_static.route('/<path:filename>') def static(filename): print(filename) return send_from_directory(app.root_path + '/web/statics/',filename) 1.1.2、www.py 路由文件 # _*_ coding:utf-8 _*_ from application import app # 引用路由文件 from web.controllers.index import home app.register_blueprint(home,url_prefix='/')
部署到生成环境不需要这个文件,只是解决本地静态文件无法加载问题。其中的url管理类为:
# -*- coding: utf-8 -*-
class UrlManager(object):
def __init__(self):
pass
@staticmethod
def buildUrl( path ):
return path
@staticmethod
def buildStaticUrl(path):
ver = "%s"%( 22222222 )
path = "/static" + path + "?ver=" + ver
return UrlManager.buildUrl( path )
# -*- coding: utf-8 -*- from application import app,manager,db from flask_script import Server import www from jobs.launcher import runJob from flask_migrate import Migrate,MigrateCommand from flask_sqlalchemy import SQLAlchemy ##web server manager.add_command( "runserver", Server( host='0.0.0.0',port=app.config['SERVER_PORT'],use_debugger = True ,use_reloader = True) ) #job entrance manager.add_command('runjob', runJob() ) # migrate = Migrate(app,db) # manager.add_command('db',MigrateCommand) def main(): manager.run( ) if __name__ == '__main__': try: import sys sys.exit( main() ) # 启动退出程序 except Exception as e: import traceback traceback.print_exc() # trackback模块可以捕获异常并打印全面的异常信息
到这里准备工作基本就做完了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。