【问题标题】:Flask-SQLAlchemy: SAWarning: Identity map already had an identity for (object), replacing it with newly flushed objectFlask-SQLAlchemy:SAWarning:身份映射已经有(对象)的身份,用新刷新的对象替换它
【发布时间】:2021-04-11 07:09:28
【问题描述】:

所以我制作了一个个人网络服务器来抓取一些网站并在网页上显示数据。但是当我尝试将结果提交到数据库时,我收到了我提交的每个视频的警告。我想知道这个警告是否可以修复或至少隐藏?

这是我的代码:

from web_scraper import db
from web_scraper.models import Video

old_db = Video.query.all() # existing database to compare with the new one
db_queue = list() # scraping results ready to be added to the database

### web scraping occurs here to fill db_queue

db.drop_all() # reset db
db.create_all() # recreate a new one
for vid in db_queue:
    db.session.add(vid) # adding all pending results
db.session.commit() # error thrown here

这是完整的警告输出:

C:\DevApps\Python38\lib\site-packages\sqlalchemy\orm\session.py:1948: SAWarning: Identity map already had
an identity for (<class 'web_scraper.models.Video'>, (2133,), None), replacing it with newly flushed object.
Are there load operations occurring inside of an event handler within the flush?

【问题讨论】:

  • 尝试在db.create_all之前做commit
  • @sahasrara62 我收到了这个错误sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: video sqlalche.me/e/13/e3q8

标签: python python-3.x sqlalchemy flask-sqlalchemy


【解决方案1】:

发出此警告是因为:

  • 会话已创建
  • 现有对象被提取到会话中
  • 数据库表被删除并重新创建
  • 新对象被添加到同一个会话
  • 新对象与添加到原始会话的对象具有相同的 ID,因此 SQLAlchemy 警告会话中的原始对象正在被新对象覆盖

old_db 中的对象仍然是原始对象,因此您可以选择忽略警告,但通常最好在警告导致错误之前处理它们(这就是警告的原因)。

您可以采取以下一个或两个步骤:

  • 关闭*原始会话并在添加新对象之前打开一个新会话
  • 不要删除并重新创建表,而是删除它们包含的对象

* 或remove 如果是scoped_session

【讨论】:

    【解决方案2】:

    感谢snakecharmerb's answer 这段代码帮助了我

    1. 关闭与数据库的连接
    2. 重新创建数据库
    3. 重新建立与数据库的连接
    db.session.close()
    db.drop_all()
    db.create_all()
    

    注意:执行此代码时,数据库将连同其中的数据一起被删除。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-10
      • 2015-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-02
      相关资源
      最近更新 更多