执行 Flask 命令报错 AssertionError: The sqlalchemy extension was not registered to the current application. Please make sure to call init_app() first

def create_app(config_name=None):
    if config_name is None:
        config_name = os.getenv('FLASK_CONFIG', 'development')

    app = Flask("bluelog")
    app.config.from_object(config[config_name])

    register_logging(app)  # 注册日志处理器
    register_extensions(app)  # 注册扩展(扩展初始化)
    register_blueprints(app)  # 注册蓝本
    register_commands(app)  # 注册自定义shell命令
    register_errors(app)  # 注册错误处理函数
    register_shell_context(app)  # 注册shell上下文处理函数
    register_template_context(app)  # 注册模板上下文处理函数
    return app

def register_extensions(app):
    bootstrap.init_app(app)
    db.init_app(app)
    moment.init_app(app)
    mail.init_app(app)
    ckeditor.init_app(app)

当我在终端执行自定义指令flask forge(向数据库生成虚拟数据)时,有一个报错;
AssertionError: The sqlalchemy extension was not registered to the current application. Please make sure to call init_app() first;
后面我把register_extensions(app)里面的 db.init_app(app) 移动到create_app(config_name=None)
中,执行flask forge,这次成功执行了;
但是我看到教程里面的是第一种,在我看来,第一种不是把app传入到了register_extensions中执行了db.init_app吗,那应该是可以的呀,为什么会报错呢?

更新:当我把 db.init_app(app) 放到 moment.init_app(app) 下面时,能执行flask forge成功,把moment.init_app(app) 这行删除掉,也能执行成功,当moment.init_app(app)出现db.init_app(app)前面时就执行报错,这是什么原理呢?

发一下完整的错误回溯(报错输出)看看?

(myweb) E:\myweb\bluelog>flask forge
Traceback (most recent call last):
File “C:\Users\AOC\AppData\Local\Programs\Python\Python38\lib\runpy.py”, line 192, in _run_module_as_main
return _run_code(code, main_globals, None,
File “C:\Users\AOC\AppData\Local\Programs\Python\Python38\lib\runpy.py”, line 85, in run_code
exec(code, run_globals)
File "E:\myweb\Scripts\flask.exe_main
.py", line 7, in
File “e:\myweb\lib\site-packages\flask\cli.py”, line 994, in main
cli.main(args=sys.argv[1:])
File “e:\myweb\lib\site-packages\flask\cli.py”, line 600, in main
return super().main(*args, **kwargs)
File “e:\myweb\lib\site-packages\click\core.py”, line 1053, in main
rv = self.invoke(ctx)
File “e:\myweb\lib\site-packages\click\core.py”, line 1659, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File “e:\myweb\lib\site-packages\click\core.py”, line 1395, in invoke
return ctx.invoke(self.callback, **ctx.params)
File “e:\myweb\lib\site-packages\click\core.py”, line 754, in invoke
return __callback(*args, **kwargs)
File “e:\myweb\lib\site-packages\click\decorators.py”, line 26, in new_func
return f(get_current_context(), *args, **kwargs)
File “e:\myweb\lib\site-packages\flask\cli.py”, line 444, in decorator
return _ctx.invoke(f, *args, **kwargs)
File “e:\myweb\lib\site-packages\click\core.py”, line 754, in invoke
return callback(*args, **kwargs)
File "E:\myweb\bluelog_init
.py", line 89, in forge
db.drop_all()
File "e:\myweb\lib\site-packages\flask_sqlalchemy_init
.py", line 1102, in drop_all
self.execute_for_all_tables(app, bind, ‘drop_all’)
File "e:\myweb\lib\site-packages\flask_sqlalchemy_init
.py", line 1086, in execute_for_all_tables
op(bind=self.get_engine(app, bind), **extra)
File "e:\myweb\lib\site-packages\flask_sqlalchemy_init
.py", line 1008, in get_engine
state = get_state(app)
File "e:\myweb\lib\site-packages\flask_sqlalchemy_init
.py", line 625, in get_state
assert ‘sqlalchemy’ in app.extensions,
AssertionError: The sqlalchemy extension was not registered to the current application. Please make sure to call init_app() first.

看起来似乎和上面的文件里的 forge 函数有关,或者是命令注册有问题。不太清楚和 flask-moment 扩展的冲突是如何导致的。如果把代码放到 GitHub 上我可以去执行试试看。