之前文章大概介绍了 SQLAlchemy
,我们今天讲下flask
中的Flask-SQLAlchemy
,大概用法跟原生的很像,但是配置使用起来更简单了。
环境准备 项目结构 我们在这里仿照Django
的目录结构来创建一个项目,这种项目结构也是Flask
官方建议的
我们的项目结构大概如下:
1 2 3 4 5 6 └── app # 应用目录 ├ ├── static # 静态文件目录 ├ ├── templates # 模板文件目录 ├ ├── views # 蓝图目录(视图文件) ├ ├── __init__.py # 应用导入时执行文件 └──manage.py # 项目入口文件
views
目录中我们写一个蓝图user.py
,代码如下:
1 2 3 4 5 6 7 8 9 10 from flask import Blueprintuser = Blueprint('user' , __name__) @user.route('/users' ) def users (): return '这里是users视图'
app/__init__.py
文件代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 from flask import Flaskfrom .views.user import userdef cerate_app (): my_app = Flask(__name__) my_app.register_blueprint(user) return my_app
manage.py
文件代码如下:
1 2 3 4 5 6 7 8 9 import appmy_app = app.cerate_app() if __name__ == '__main__' : my_app.run(debug=True )
Flask
应用创建这里同样默认你已经安装好了 Flask-SQLAlchemy
(没有安装请使用 pip install Flask-SQLAlchemy
进行安装)
修改app/__init__.py
引入Flask-SQLAlchemy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 from flask import Flaskfrom flask_sqlalchemy import SQLAlchemyfrom .views.user import userdb = SQLAlchemy() def create_app (): my_app = Flask(__name__) my_app.config["SQLALCHEMY_DATABASE_URI" ] = "mysql+pymysql://root:@127.0.0.1:3306/sqlalchemysss?charset=utf8" my_app.config["SQLALCHEMY_POOL_SIZE" ] = 5 my_app.config["SQLALCHEMY_POOL_TIMEOUT" ] = 15 my_app.config["SQLALCHEMY_TRACK_MODIFICATIONS" ] = False db.init_app(my_app) my_app.register_blueprint(user) return my_app
创建models.py
创建orm
模型文件,类似Django
中的models
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from app import dbclass User (db.Model): __tablename__ = "app_users" __table_args__ = {"useexisting" : True } id = db.Column(db.Integer, primary_key=True ) name = db.Column(db.String(32 ), comment="姓名" ) if __name__ == '__main__' : from app import create_app my_app = create_app() db.drop_all(app=my_app) db.create_all(app=my_app)
修改视图 app/views/user.py
调用models
模型,使用该模型进行增查
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 from flask import Blueprint,jsonifyfrom app.models import Userfrom app import dbuser = Blueprint("user" ,__name__) @user.route("/users/ass" ) def add (): db.session.add(User(name="张学友" )) db.session.commit() return "添加用户" @user.route("/users" ) def users (): res = User.query.all () user = [] for item in res: user.append({"name" :item.name, "id" :item.id }) return jsonify(user)
此时运行flask项目,单独执行models.py
进行数据表创建,此时访问路由程序正常运行
使用Flask-Script
我们继续仿照Django
进行操作,Django
给我们提供了命令来运行django
程序,我们要实现类似功能需要借助第三方扩展包Flask-Script
。
1 2 3 4 5 6 7 8 9 10 11 12 from flask_script import Managerimport appmy_app = app.create_app() manager = Manager(my_app) if __name__ == '__main__' : manager.run()
使用flask_script
命令行 使用command 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 from flask_script import Managerimport appmy_app = app.create_app() manager = Manager(my_app) @manager.command def outName (name ): print (f"你好{name} " ) if __name__ == '__main__' : manager.run()
测试我们控制台使用python manager.py outName 刘德华
,控制台就会打印“你好刘德华”
使用option
option
命令语法如下: @manager.opation("-短指令","--长指令",dest="变量名")
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 from flask_script import Managerimport appmy_app = app.create_app() manager = Manager(my_app) @manager.command def outName (name ): print (f"你好{name} " ) @manager.option('-ip' , '--ipaddress' , dest = "ip" ) @manager.option('-p' , '--port' , dest = "port" ) def runApp (ip, port ): print (f"程序运行在:{ip} 上,且端口为:{port} " ) if __name__ == '__main__' : manager.run()
测试我们测试一下命令,无论长指令还是短指令都正确输出了
1 2 3 4 5 6 E:\site>python manager.py runApp -ip 10.10.10.222 -p 9999 程序运行在:10.10.10.222上,且端口为:9999 E:\site>python manager.py runApp --ipaddress 10.10.10.111 --port 8888 程序运行在:10.10.10.111上,且端口为:8888
使用指令 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 from flask_script import Managerimport appmy_app = app.create_app() manager = Manager(my_app) @manager.option('-ip' , '--ipaddress' , dest = "ip" ) @manager.option('-p' , '--port' , dest = "port" ) def runApp (ip, port ): my_app.run("0.0.0.0" , int (port),debug=True ) if __name__ == '__main__' : manager.run()
测试 经测试,跟Django
一样的效果,完成了
1 2 3 4 5 6 7 8 9 10 11 E:\site>python manager.py runApp -ip 0.0.0.0 -p 9588 * Serving Flask app "app" (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: on * Restarting with stat * Debugger is active! * Debugger PIN: 339-556-363 * Running on http://0.0.0.0:9588/ (Press CTRL+C to quit)
Flask-Migrate
上方代码执行的前提还是要先手动执行models.py
文件,让其创建数据表,我们既然知道了创建命令是否可以把类似Django
的数据库迁移也做出来?这就用到了另一个第三方库Flask-Migrate
,该扩展库必须是要基于flask_script
。
安装 Flask-Migrate
1 pip install Flask-Migrate
引入Flask-Migrate
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 from flask_script import Managerfrom flask_migrate import Migrate, MigrateCommandimport appmy_app = app.create_app() manager = Manager(my_app) Migrate(my_app, app.db) manager.add_command("db" , MigrateCommand) """ 数据库迁移指令: python manager.py db init python manager.py db migrate # Django中的 makemigration python manager.py db upgrade # Django中的 migrate """ @manager.option('-ip' , '--ipaddress' , dest = "ip" ) @manager.option('-p' , '--port' , dest = "port" ) def runApp (ip, port ): my_app.run("0.0.0.0" , int (port),debug=True ) return "程序运行成功!!!" if __name__ == '__main__' : manager.run()
执行 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 E:\site>python manager.py db init Creating directory E:\site\migrations ... done Creating directory E:\site\migrations\versions ... done Generating E:\site\migrations\alembic.ini ... done Generating E:\site\migrations\env.py ... done Generating E:\site\migrations\README ... done Generating E:\site\script.py.mako ... done Please edit configuration/connection/logging settings in 'E:\\site\\migratio ns\\alembic.ini' before proceeding. E:\site>python manager.py db migrate D:\Program Files\Python37\lib\site-packages\pymysql\cursors.py:170: Warning: (1366, "Incorrect string valu e: '\\xD6\\xD0\\xB9\\xFA\\xB1\\xEA...' for column 'VARIABLE_VALUE' at row 484") result = self._query(query) INFO [alembic.runtime.migration] Context impl MySQLImpl. INFO [alembic.runtime.migration] Will assume non-transactional DDL. INFO [alembic.autogenerate.compare] Detected removed table 'teachers' INFO [alembic.autogenerate.compare] Detected removed table 'app_users' INFO [alembic.autogenerate.compare] Detected removed table 'students' INFO [alembic.autogenerate.compare] Detected removed table 'citys' INFO [alembic.autogenerate.compare] Detected removed table 'user' INFO [alembic.autogenerate.compare] Detected removed table 'studentteacher' Generating E:\site\migrations\versions\ed69f0263233_.py ... done E:\site>python manager.py db upgrade D:\Program Files\Python37\lib\site-packages\pymysql\cursors.py:170: Warning: (1366, "Incorrect string valu e: '\\xD6\\xD0\\xB9\\xFA\\xB1\\xEA...' for column 'VARIABLE_VALUE' at row 484") result = self._query(query) INFO [alembic.runtime.migration] Context impl MySQLImpl.
执行成功,此时查看数据表正常,且文件夹目录多了一个migrations文件夹