V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
Mrkon
V2EX  ›  Python

关于 flask-sqlalchemy 的一个问题

  •  
  •   Mrkon · 2018-08-03 11:22:02 +08:00 · 2894 次点击
    这是一个创建于 2305 天前的主题,其中的信息可能已经有所发展或是发生改变。
    在 user 中调用外键,出现如下错误:

    DetachedInstanceError:arent instance is not bound to a Session, and no contextual session is established; lazy load operation of attribute 'key' cannot proceed

    通过查找与测试:
    1、将 lazy 改为'subquery'后可用,但是我需要使用 filter_by 查找,放弃

    2、使用
    if 'obj' not in db.session:
    obj = db.session.merge(obj)
    会产生 unique 的错误

    3、发现在调用的时候
    user = User()
    print user not in db.session
    返回的为 True,请问一下这是什么原因?
    求解答

    4、问题已暴力解决
    直接在调用的时候就在 db.session 中加入 user
    user = User()
    if user not in db.session:
    user = db.session.merge(user)

    但是求大神解答一下问题 3 !!!
    9 条回复    2020-09-14 22:47:16 +08:00
    owenliang
        1
    owenliang  
       2018-08-03 15:03:58 +08:00
    这个库意义不大,不如 dbutils 搞个 mysql-python 的连接池用。
    mrchi
        2
    mrchi  
       2018-08-03 15:12:00 +08:00
    lazy 参数改为 "dynamic" 试试?如果贴一下完整代码更好
    Mrkon
        3
    Mrkon  
    OP
       2018-08-03 18:05:20 +08:00
    @mrchi 使用的就是 dynamic,不然怎么 filter_by 呢
    Mrkon
        4
    Mrkon  
    OP
       2018-08-03 18:06:43 +08:00
    @owenliang 习惯使用这个 ORM 了,一般做开发都不是用这个吗?
    mrchi
        5
    mrchi  
       2018-08-03 22:52:10 +08:00   ❤️ 1
    @Mrkon 好吧,那我说一下问题 3。

    User 是数据库模型,也是 Class,u = User() 是创建了 User 类的一个实例,这个时候跟 db.session 是无关的,如果要写到数据库里,在 commit 之前,需要执行 db.session.add (我一般用的 add,没用过 merge );但如果 u 是通过数据库查出来的,比如 u = User.query.get(1),这个时候 u 是默认在 session 中的。

    不知道这样说你能不能理解。另外好奇 merge 和 add 有什么不同
    Mrkon
        6
    Mrkon  
    OP
       2018-08-04 12:26:43 +08:00
    @mrchi 感谢
    我在网上查找到:
    使用 session.merge() 方法替代 session.add(),其实就是 SELECT + UPDATE

    其实我感到最疑惑的一点是我在两个项目用了相同的函数,但是一个不用将 u = User ()加入到 session 中,另外一个需要,一开始怀疑是自动 commit,但是并没有发现自动提交的代码。我使用的是 flask
    mrchi
        7
    mrchi  
       2018-08-04 14:21:59 +08:00
    @Mrkon 这个 merge 有意思,哈哈哈

    关于自动 commit,Flask-sqlalchemy 有一个配置项 SQLALCHEMY_COMMIT_ON_TEARDOWN,目前最新的版本默认是 False 的,如果设置为 True 就会自动 commit。

    另外,Flask-sqlalchemy 准备删除这个配置,也就是去掉自动 commit 这个功能,参考这个 [issue]( https://github.com/mitsuhiko/flask-sqlalchemy/issues/216) 中的讨论。目前,文档中已经删掉了这个配置的信息,但代码中(`https://github.com/mitsuhiko/flask-sqlalchemy/blob/master/flask_sqlalchemy/__init__.py`,L791 )还是存在这个配置的,也就是说还能用,但最好不要再用了,推荐手动 commit。
    Mrkon
        8
    Mrkon  
    OP
       2018-08-04 15:08:53 +08:00
    @mrchi 恩,谢谢,但是奇怪的是,我在配置项里面没有使用 SQLALCHEMY_COMMIT_ON_TEARDOWN,并且手动把 SQLALCHEMY_COMMIT_ON_TEARDOWN 设置成 False 也同样报错,这就很奇特了
    cqzhao
        9
    cqzhao  
       2020-09-14 22:47:16 +08:00
    我有遇到了这个问题。请问怎么解决的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2486 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 15:49 · PVG 23:49 · LAX 07:49 · JFK 10:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.