ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

新版Flask-SQLAlchemy和Flask-Migrate的踩坑指南(2022.07)

2022-07-22 23:31:09  阅读:247  来源: 互联网

标签:SQLAlchemy Flask py db Migrate orm user flask admin


一、版本环境

看了很多文章,没有写清楚环境的版本,导致解决方案根本对不上号,所以我先把本人使用的主要模块版本列出来

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)

结果遇到一些错误,下面一一说明。

1.No module named 'flask._compat'

完整提示:

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 ,欢迎访问

标签:SQLAlchemy,Flask,py,db,Migrate,orm,user,flask,admin
来源: https://www.cnblogs.com/achillis/p/16508259.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有