看了很多文章,没有写清楚环境的版本,导致解决方案根本对不上号,所以我先把本人使用的主要模块版本列出来
Flask==2.1.3 Flask-Migrate==3.1.0 Flask-Script==2.0.6 Flask-SQLAlchemy==2.5.1
本人开发环境为Windows + VSCode
一开始,我按照网上的大部分教程所说,使用flask_script来执行数据迁移命令,主要代码如下:
from flask_migrate import Migrate,MigrateCommand from flask_script import Manager manager = Manager(app) # flask-script集成的数据库操作 manager.add_command('db', MigrateCommand)
结果遇到一些错误,下面一一说明。
完整提示:
F:\Python\flask\flask_orm_admin>python3 main.py db init Traceback (most recent call last): File "main.py", line 6, in <module> from flask_script import Manager File "D:\Python3\lib\site-packages\flask_script\__init__.py", line 15, in <module> from flask._compat import text_type ModuleNotFoundError: No module named 'flask._compat'
然后搜解决办法,发现很多人给的解决办法就是降低Flask的版本,改用1.x的版本
我了个去,这叫什么解决方案?以后还都不用新版本了?后来找到一个靠谱的解决办法:
修改flask_script 文件就可以 It happened because the python searched on Flask._compat directory and It isn't there, so I changed like on below : (on flask_script/__init__.py) Where: from ._compat import text_type on original flask-script file to : from flask_script._compat import text_type
试了一下,果然不再报这个错了,踩过了第一个坑。
然后继续按网上教程操作,又遇到一个坑。。
2.cannot import name 'MigrateCommand' from 'flask_migrate'
完整提示“:
F:\Python\flask\flask_orm_admin>python3 main.py db init Traceback (most recent call last): File "main.py", line 5, in <module> from flask_migrate import Migrate,MigrateCommand ImportError: cannot import name 'MigrateCommand' from 'flask_migrate' (D:\Python3\lib\site-packages\flask_migrate\__init__.py)
其实我还没运行的时候,我的VSCode已经提示我找不到MigrateCommand了
解决办法:
网上一搜,给出的解决方案又是降级!真是服了!继续找,终于找到一篇有用的 https://www.jianshu.com/p/11ce08e078aa
发现flask_migrate已经不再支持flask_script了,所以没有了MigrateCommand
因此,在我的代码中去掉了flask_script相关的内容,对代码进行了调整。
准备就绪之后,开始数据迁移工作
由于不再使用flask_script,而是使用flask db命令,所以跟网上的教程有一些变化
执行flask db init,会报错:
F:\Python\flask\flask_orm_admin\server>flask db init Usage: flask db init [OPTIONS] Try 'flask db init --help' for help. Error: Could not locate a Flask application. You did not provide the "FLASK_APP" environment variable, and a "wsgi.py" or "app.py" module wa s not found in the current directory.
就是说,flask需要找到一个Flask的实例app,FLASK_APP通常指定为主程序
set FLASK_APP=main.py
然后再执行flask db init
此时可能会出现导入模块错误,比如找不到连接数据库的ext.py,考虑到应该是因为直接执行flask命令时可能找不到本项目的路径,需要在main.py头部加上一些代码:
import sys,os curdir = os.path.dirname(__file__) sys.path.append(curdir) sys.path.append(curdir + "..\\")
这样就可以解决找不到模块的问题了,继续执行
F:\Python\flask\flask_orm_admin\server>flask db init Creating directory F:\Python\flask\flask_orm_admin\server\migrations\versions ... done Generating F:\Python\flask\flask_orm_admin\server\migrations\alembic.ini ... done Generating F:\Python\flask\flask_orm_admin\server\migrations\env.py ... done Generating F:\Python\flask\flask_orm_admin\server\migrations\README ... done Generating F:\Python\flask\flask_orm_admin\server\migrations\script.py.mako ... done Please edit configuration/connection/logging settings in 'F:\\Python\\flask\\flask_orm_admin\\server\\migrations\\alembic.ini' before proceeding.
这个提示信息看起来是正常的,继续执行flask db migrate,-m参数可以为本次迁移添加一个消息,就像git的提交消息一样,后续一旦有问题还可以回滚
F:\Python\flask\flask_orm_admin\server>flask db migrate -m "add t_user" INFO [alembic.runtime.migration] Context impl SQLiteImpl. INFO [alembic.runtime.migration] Will assume non-transactional DDL. INFO [alembic.autogenerate.compare] Detected added table 't_user' Generating F:\Python\flask\flask_orm_admin\server\migrations\versions\5c8e40bf5e34_add_t_user.py ... done
提示信息正常,检测到新表t_user,并生成了一个5c8e40bf5e34_add_t_user文件,有兴趣的读者可以根据路径找到这个文件,看看里面的内容
接下来执行flask db upgrade
F:\Python\flask\flask_orm_admin\server>flask db upgrade INFO [alembic.runtime.migration] Context impl SQLiteImpl. INFO [alembic.runtime.migration] Will assume non-transactional DDL. INFO [alembic.runtime.migration] Running upgrade -> 5c8e40bf5e34, add t_user
没有报错,应该是正常的。此时可以打开数据库检查一下,会发现t_user表已经建立好了
接下来再添加一个t_admin表,建立相应的Model,在main.py中添加导入,然后重复migrate和upgrade的过程
F:\Python\flask\flask_orm_admin\server>flask db migrate -m "add t_admin" INFO [alembic.runtime.migration] Context impl SQLiteImpl. INFO [alembic.runtime.migration] Will assume non-transactional DDL. INFO [alembic.autogenerate.compare] Detected added table 't_admin' Generating F:\Python\flask\flask_orm_admin\server\migrations\versions\d91575857413_add_t_admin.py ... done F:\Python\flask\flask_orm_admin\server>flask db upgrade INFO [alembic.runtime.migration] Context impl SQLiteImpl. INFO [alembic.runtime.migration] Will assume non-transactional DDL. INFO [alembic.runtime.migration] Running upgrade 5c8e40bf5e34 -> d91575857413, add t_admin
检查了一下也是正常的。
其它的一些情况,我把注释都写在源码里了,自行查看即可
使用著名的Faker库,来向user表添加一些数据。
import sys sys.path.append("..") from faker import Faker from main import create_app #导入模型 from user.models import User fake = Faker(locale="zh-CN") app = create_app() db = app.config["db"] #添加10个用户 def addFakeUser(): try: with app.app_context(): for _ in range(10): user = User(username=fake.name()) user.password = fake.random_number(7) user.email = fake.email() user.phone = fake.phone_number() user.money = fake.random_int() user.userip = fake.ipv4() print(user.username,user.email) #添加并提交 db.session.add(user) db.session.commit() except Exception as e: print("数据库操作失败") raise else: return True addFakeUser()
然后访问接口http://127.0.0.1:5000/user/list,就可以看到数据了!
相关代码已放在 https://gitee.com/achillis/flask_demo ,欢迎访问