【问题标题】:Flask app wont launch 'ImportError: cannot import name 'cached_property' from 'werkzeug' 'Flask 应用程序不会启动 'ImportError: cannot import name 'cached_property' from 'werkzeug'
【发布时间】:2020-02-10 18:20:39
【问题描述】:

我已经在 Flask 应用程序上工作了几个星期。我今天完成它并去部署它......现在它不会启动。

我没有添加或删除任何代码,所以假设部署过程中发生了一些变化?

无论如何,这是终端中显示的完整错误:

Traceback (most recent call last):
  File "C:\Users\Kev\Documents\Projects\Docket\manage.py", line 5, in <module>
    from app import create_app, db
  File "C:\Users\Kev\Documents\Projects\Docket\app\__init__.py", line 21, in <module>
    from app.api import api, blueprint, limiter
  File "C:\Users\Kev\Documents\Projects\Docket\app\api\__init__.py", line 2, in <module>
    from flask_restplus import Api
  File "C:\Users\Kev\.virtualenvs\Docket-LasDxOWU\lib\site-packages\flask_restplus\__init_
_.py", line 4, in <module>
    from . import fields, reqparse, apidoc, inputs, cors
  File "C:\Users\Kev\.virtualenvs\Docket-LasDxOWU\lib\site-packages\flask_restplus\fields.
py", line 17, in <module>
    from werkzeug import cached_property
ImportError: cannot import name 'cached_property' from 'werkzeug' (C:\Users\Kev\.virtualen
vs\Docket-LasDxOWU\lib\site-packages\werkzeug\__init__.py)

这也是提到的三个文件中的代码。

manage.py:

from apscheduler.schedulers.background import BackgroundScheduler
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand

from app import create_app, db

app = create_app()
app.app_context().push()

manager = Manager(app)

migrate = Migrate(app, db)

manager.add_command('db', MigrateCommand)

from app.routes import *
from app.models import *

def clear_data():
    with app.app_context():
        db.session.query(User).delete()
        db.session.query(Todo).delete()
        db.session.commit()
        print("Deleted table rows!")

@manager.command
def run():
    scheduler = BackgroundScheduler()
    scheduler.add_job(clear_data, trigger='interval', minutes=15)
    scheduler.start()
    app.run(debug=True)

if __name__ == '__main__':
    clear_data()
    manager.run()

app/__init__.py:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager

from config import Config

db = SQLAlchemy()

login = LoginManager()

def create_app():
    app = Flask(__name__)
    app.config.from_object(Config)
    db.init_app(app)

    login.init_app(app)
    login.login_view = 'login'

    from app.api import api, blueprint, limiter
    from app.api.endpoints import users, todos, register
    from app.api.endpoints.todos import TodosNS
    from app.api.endpoints.users import UserNS
    from app.api.endpoints.register import RegisterNS

    api.init_app(app)

    app.register_blueprint(blueprint)

    limiter.init_app(app)

    api.add_namespace(TodosNS)
    api.add_namespace(UserNS)
    api.add_namespace(RegisterNS)

    return app

api/__init__.py:

from logging import StreamHandler
from flask_restplus import Api
from flask import Blueprint
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address

blueprint = Blueprint('api', __name__, url_prefix='/api')

limiter = Limiter(key_func=get_remote_address)
limiter.logger.addHandler(StreamHandler())

api = Api(blueprint, doc='/documentation', version='1.0', title='Docket API',
          description='API for Docket. Create users and todo items through a REST API.\n'
                      'First of all, begin by registering a new user via the registration form in the web interface.\n'
                      'Or via a `POST` request to the `/Register/` end point', decorators=[limiter.limit("50/day", error_message="API request limit has been reached (50 per day)")])

我尝试重新安装 flaskflask_restplus 但没有成功。

【问题讨论】:

  • 看起来 Werkzeug 1.0.0 已经发布,这在其他地方引起了this error。然而 Flask-Restplus 也是unmaintained。您可以考虑移至flask-restx 或尝试在您的要求中固定至Werkzeug==0.16.1
  • 在python 3.8中你可以from functools import cached_property

标签: python flask flask-restplus


【解决方案1】:

2020 年 5 月的正确答案:flask-restplus 已死,移至 flask-restx

来自noirbizarre/flask-restplus#778 (comment)

由于维护者没有 pypi 密钥,flask-restplus 的工作已经停止。查看替代品的下降,flask-restx。这是维护团队的官方分叉。我们已经解决了那里的问题

来自noirbizarre/flask-restplus#777 (comment)

没有。 Flask-restplus 不再维护。以前的维护者没有权限推送到 pypi,经过几个月的尝试,我们分叉了这个项目。查看烧瓶-restx。这是替代品的下降,我们正在制定路线图、设计和修复……例如,我们已经为 Werkzeug 打了补丁

因此,真正的解决方案是迁移到 flask-restx,而不是固定到 Werkzeug 的旧版本。

【讨论】:

    【解决方案2】:

    降级到 Werkzeug==0.16.1 解决了这个问题

    https://github.com/noirbizarre/flask-restplus/issues/777#issuecomment-583235327

    编辑

    想补充一点,永久(长期)解决方案是移至flask_restx,因为不再维护flask-restplus

    how to migrate from flask-restplus

    【讨论】:

    • 物有所值。是时候转移到flask_restx,因为flask-restplus 没有得到维护。这将解决 werkzeug 问题。
    【解决方案3】:

    试试:

    from werkzeug.utils import cached_property
    

    https://werkzeug.palletsprojects.com/en/1.0.x/utils/

    【讨论】:

    【解决方案4】:

    将 Werkzeug 降级到 0.16.1

    pip3 install --upgrade Werkzeug==0.16.1
    

    如果您执行pip3 list,您可能会看到如下内容:

    Flask              1.1.2
    Werkzeug           0.16.1
    

    【讨论】:

      【解决方案5】:

      为了修复这个痛苦的错误是为了确定在文件 PipFile.lock 中安装新包后发生的情况是做一个 diff 文件并找到差异:

      我在安装包后发现werkzeug包将她的版本“version”:“==0.15.2”改为“version”:“==1.0.1”当尝试执行命令sudo docker-compose build 时给我错误。

      为了解决这个错误,我这样做了:

      放弃所有更改并重新开始。

      停止并删除您以前的 docker

      sudo docker stop $(sudo docker ps -aq)

      sudo docker rm $(sudo docker ps -aq)

      再次执行docker:

      sudo docker-compose build

      sudo docker-compose up

      进入docker内部,获取docker的id:先按CRTL+z暂停docker,然后在终端执行

      sudo docker ps

      获取CONTAINER ID列的编号

      执行:sudo docker exec -it 23f77dbefd57 bash 用于进入 docker 终端

      现在执行你想要的包,在我的例子中是 SOAPpy,像这样

       `pipenv install SOAPpy`
      

      在这个安装之后,安装之前的 werkzeug 包在我的例子中是

      pipenv install Werkzeug==0.15.2

      在终端中写exit并按“Enter”,关闭docker内的终端。

      如果您比较文件 Pipfile.lock 具有相同的版本,这是真正的修复。

      最后的步骤是:停止,再次构建和启动 docker:

      sudo docker stop $(sudo docker ps -aq)

      sudo docker-compose build

      sudo docker-compose up

      现在再次运行 docker:

      给自己的一个便条,我只是想提醒你,你有能力 一切都不要轻易放弃,记住总有一个 方式,它只是连接点。 永不放弃不战斗。

      【讨论】:

        【解决方案6】:

        这可能太奇怪了,不会发生在其他人身上,但是……检查你实际导入的包。我的看起来像这样:

        很明显,这里的导入有些麻烦...删除并读取了正确的“werkzeug”包并且它“工作”(结果我仍然需要实施提供给这个的其他解决方案之一问题... :-( )

        啊-但是你问:“我如何删除这样一个损坏的包?GUI 不允许我!!”。不要害怕,我也遇到过这种情况。在 Pycharm 中,通过将鼠标悬停在设置菜单下的包名称上来找到包文件位置,在文件资源管理器中转到那里,然后删除文件夹和其他类似内容。然后使用 GUI 重新安装软件包。

        【讨论】:

          猜你喜欢
          • 2022-01-21
          • 2022-10-15
          • 2019-07-20
          • 2020-07-16
          • 2019-06-10
          • 2014-09-25
          • 2014-01-02
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多