【问题标题】:Access to app.models from python terminal in app with Flask's Application factory使用 Flask 的应用程序工厂从应用程序中的 python 终端访问 app.models
【发布时间】:2021-04-19 04:10:04
【问题描述】:

我配置了应用程序以使用应用程序工厂。应用运行良好,我可以登录、创建用户、从 Postgres DB 查询信息、迁移表等。

我曾经在 Python 控制台中从模型中查询数据以检查状态并在应用程序工厂更改之前测试一些 ORM 配置,我曾经运行这些命令并获得响应

PC:~/exercises/$ python
Python 3.8.5 (default, Sep  4 2020, 07:30:14) 
>>> from app.models import *
>>> User.query.all()

应用配置后,我尝试检索查询。导入表不返回任何错误,但查询返回此错误:

>>> from app.models import *
>>> User.query.all()
Traceback (most recent call last):
  File "/home/dannisis/dock_exercise/emailservices/env/lib/python3.8/site-packages/sqlalchemy/util/_collections.py", line 1008, in __call__
    return self.registry[key]
KeyError: <greenlet.greenlet object at 0x7f0cb7196bf0 (otid=0x7f0cb818dd40) current active started main>

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/dannisis/dock_exercise/emailservices/env/lib/python3.8/site-packages/flask_sqlalchemy/__init__.py", line 552, in __get__
    return type.query_class(mapper, session=self.sa.session())
  File "/home/dannisis/dock_exercise/emailservices/env/lib/python3.8/site-packages/sqlalchemy/orm/scoping.py", line 129, in __call__
    return self.registry()
  File "/home/dannisis/dock_exercise/emailservices/env/lib/python3.8/site-packages/sqlalchemy/util/_collections.py", line 1010, in __call__
    return self.registry.setdefault(key, self.createfunc())
  File "/home/dannisis/dock_exercise/emailservices/env/lib/python3.8/site-packages/sqlalchemy/orm/session.py", line 4044, in __call__
    return self.class_(**local_kw)
  File "/home/dannisis/dock_exercise/emailservices/env/lib/python3.8/site-packages/flask_sqlalchemy/__init__.py", line 174, in __init__
    self.app = app = db.get_app()
  File "/home/dannisis/dock_exercise/emailservices/env/lib/python3.8/site-packages/flask_sqlalchemy/__init__.py", line 1042, in get_app
    raise RuntimeError(
RuntimeError: No application found. Either work inside a view function or push an application context. See http://flask-sqlalchemy.pocoo.org/contexts/.

我尝试使用 `from create_app.models import *' 导入模型表,它也返回错误。如何在终端或控制台中检索查询

树应用简化及相关应用配置如下:

├── app
│   ├── admin
│   │   ├── forms.py
│   │   ├── __init__.py
│   │   └── views.py
│   ├── config.py
│   ├── errors
│   │   ├── forms.py
│   │   └── __init__.py
│   ├── __init__.py
│   ├── main
│   │   ├── forms.py
│   │   ├── __init__.py
│   │   ├── utils.py
│   │   └── views.py
│   ├── models.py
│   ├── static
│   │   ├── css
│   │   │   └── styles.css
│   │   ├── img
│   │   │   └── favicon.ico
│   │   └── js
│   │       └── scripts.js
│   └── templates
│       ├── account.html
│       ├── home.html
│       ├── index.html
│       └── layout.html
├── migrations
│   ├── alembic.ini
│   ├── script.py.mako
│   └── versions
│       ├── 1de2ece5a3da_initial_commit.py
│       └── 9815b2f43f0a_tabla_dependientes.py
├── requirements.txt
├── run.py
└── tree.txt

运行文件是:

from app import create_app

app = create_app()

if __name__ == "__main__":
    app.run(debug=True)

模型文件也简化为:

class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    date_created = db.Column(db.DateTime, default=datetime.utcnow)
    username = db.Column(db.String(30), unique=True, nullable=False)

app目录下的init文件包括imports和db、migrate、bcrypt等实例化和应用函数

def create_app(config_class = Config):
    app = Flask(__name__)
    app.config.from_object(Config)
    app.config['SQLALCHEMY_DATABASE_URI'] = db_prefix + f'{Config.POSTGRES_DBNAME2}'

    db.init_app(app)
    migrate.init_app(app, db)
    bcrypt.init_app(app)
    login_manager.init_app(app)
    mail.init_app(app)

    from app.main.views import main
    from app.admin.views import admin
    app.register_blueprint(main)
    app.register_blueprint(admin)

    return app

【问题讨论】:

    标签: python flask sqlalchemy


    【解决方案1】:

    使用flask shell 命令访问您的应用程序。此命令的目的是在应用程序的上下文中启动 Python 解释器。什么意思:

    $ python
    >>> from app.models import *
    >>> User.query.all()
    
    # Output
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      #...
    

    但是:

    $ flask shell
    >>> from app.models import *
    >>> User.query.all()
    
    # Output
    # ... no traceback
    

    对于常规解释器会话,除非明确导入,否则 app 是未知的,但 flask shell 会预导入您的应用程序实例。

    如何配置flask shell

    在应用程序的入口点run.py 中,配置一个shell 上下文,它是要预导入的其他符号的列表。

    # run.py
    
    from app import create_app, db
    from app.models import User
    
    app = create_app()
    
    @app.shell_context_processor
    def make_shell_context():
        return {
                'db': db,
                'User': User
                }
    
    if __name__ == "__main__":
        app.run(debug=True)
    

    在您的终端中,运行:

    $ flask shell
    >>> from app.models import *
    >>> User.query.all()
    
    # Output
    # ... no traceback
    

    【讨论】:

      猜你喜欢
      • 2019-11-07
      • 2020-09-26
      • 1970-01-01
      • 2018-10-21
      • 2014-06-20
      • 1970-01-01
      • 2019-03-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多