Pat*_*ell 17 sqlalchemy flask flask-sqlalchemy
问题
该Query.get()方法在 SQLAlchemy 2.0 中已弃用。因此,Flask-SQLAlchemy 查询接口被认为是遗留的。因此,User.query.get(1)在我的 Flask-SQLAlchemy 项目中运行会出现如下所示的遗留警告:
>>> User.query.get(1)
<stdin>:1: LegacyAPIWarning: The Query.get() method
is considered legacy as of the 1.x series of SQLAlchemy
and becomes a legacy construct in 2.0. The method is
now available as Session.get() (deprecated since: 2.0)
(Background on SQLAlchemy 2.0 at: https://sqlalche.me/e/b8d9)
<User spongebob>
Run Code Online (Sandbox Code Playgroud)
我的问题
Flask-SQLAlchemy 中新的 SQLAlchemy 2.0 兼容版本是什么User.query.get(1)?更具体地说,为什么 Flask-SQLAlchemy 文档推荐下面的方法 #2,尽管根据我对 SQLAlchemy 2.0 迁移指南的阅读,方法 #1 似乎是新版本?
方法#1:db.session.get(User, 1)
第一种方法来自 SQLAlchemy 文档,特别是SQLAlchemy 2.0 迁移 - ORM 使用指南。将该指南中的“2.0 样式”示例转换为我的 Flask-SQLAlchemy 项目会生成以下代码,该代码运行良好:
>>> db.session.get(User, 1)
<User spongebob>
Run Code Online (Sandbox Code Playgroud)
session.get()据我所知,Flask-SQLAlchemy 3.0.x 文档中没有提到这种方法,除了在get_or_404.
方法#2:db.session.execute(db.select(User).filter_by(id=1)).scalar()
这种方法来自Flask-SQLAlchemy 文档,该文档建议使用session.execute(select(...))作为旧版Model.query和的替代品session.query。这也很好用:
>>> db.session.execute(db.select(User).filter_by(id=1)).scalar()
<User spongebob>
Run Code Online (Sandbox Code Playgroud)
方法#1 与方法#2 与传统方法
方法 #1 ( db.session.get(User, 1)) 似乎与旧方法 ( User.query.get(1)) 最相似,因为它会在第一次运行时缓存结果session,并且不会对数据库发出不必要的额外调用。这可以在打开 echo 的 REPL 中看到,即db.engine.echo = True。相反,方法 #2 ( session.execute(select(...))) 每次都会按预期访问数据库。
我的设置/环境
版本:Python 3.11 虚拟环境中的 Flask 2.2.2、Flask-SQLAlchemy 3.0.3 和 SQLAlchemy 2.0.1。
我正在使用 Flask Mega-Tutorial 中定义的项目结构,特别是Part IV Database。
小智 11
根据https://docs.sqlalchemy.org/en/14/changelog/migration_20.html#orm-query-get-method-moves-to-session
Query.get() 方法仍然用于遗留目的,但主要接口现在是 Session.get() 方法:
# legacy usage
user_obj = session.query(User).get(5)
Run Code Online (Sandbox Code Playgroud)
迁移到2.0
在1.4/2.0中,Session对象增加了一个新的Session.get()方法:
# 1.4 / 2.0 cross-compatible use
user_obj = session.get(User, 5)
Run Code Online (Sandbox Code Playgroud)
与flask_sqlalchemy兼容,这应该可以很好地工作
user_obj = db.session.get(User, 5)
Run Code Online (Sandbox Code Playgroud)
小智 0
使用带有用户注册的 Flask 应用程序时,我遇到了这个问题。Flask登录文档有一个示例,有一个小错误:
@login_manager.user_loader
def load_user(user_id):
return User.get(user_id)
^^^ not correct
Run Code Online (Sandbox Code Playgroud)
所以,我把它改成了:
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
^^^^^^^^^ deprecated
Run Code Online (Sandbox Code Playgroud)
最后,我使用了方法#1,一切都很顺利:
@login_manager.user_loader
def load_user(user_id):
return db.session.get(User, int(user_id))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6797 次 |
| 最近记录: |