weixin_43789608 2019-12-18 23:12 采纳率: 0%
浏览 316

python flask_sqlalchemy如何维护一个全局查询结果

在我的webapp中,每个页面都要用到同一个一般不会变化的查询结果,为避免每次访问都需查询一次这个变量,我在views.py中弄了一个全局变量ADMIN_NOTES

ADMIN_NOTES=Note.query.filter_by(author_id=ADMIN.id).all()

而当ADMIN_NOTE会发生变化时,如此时管理员又写入了一个新note,则重新查询数据库获得最新的ADMIN_NOTE的值,尽量减少访问数据库的次数

我本想这么实现的(中间部分不重要的代码省略了)

#全局变量
ADMIN_NOTES=Note.query.filter_by(author_id=ADMIN.id).all()

#写入新note的函数1
@app.route('/new_note',methods=['GET','POST'])
def new_note():
    global ADMIN_NOTES
    data=json.loads(request.get_data())
    note=Note(title=data['note_title'],upload_time=datetime.utcnow())
    db.session.add(note)
    db.session.commit()
        #若是管理员写入新note,则重新查询并修改全局变量ADMIN_NOTES
    if note.author.nickname=='ADMIN':
        ADMIN_NOTES=Note.query.filter_by(author_id=ADMIN.id).all()
                KAFENUT_NOTES[0].author.nickname  #能正确访问ADMIN_NOTES
        print(len(ADMIN_NOTES))  #正确访问ADMIN_NOTES
    resp['success']=True
    resp['text']='Upload successfully!'
    resp['url']=url_for('note',note_id=note.id,nickname=note.author.nickname) #浏览器接受到服务器的json之后跳转到,resp[url]所指示的页面,即下面这个页面
    return json.dumps(resp)

#返回note页面的函数2
@app.route('/<nickname>/note/<note_id>',methods=['GET','POST'])
def note(nickname,note_id):
    global ADMIN_NOTES
    user=User.query.filter_by(nickname=nickname).first()
    note=Note.query.filter_by(id=note_id).first()
    if request.method=='GET':             
        note.view_num+=1
        db.session.add(note)
        db.session.commit()
        for nnote in ADMIN_NOTES: 
            print(nnote.author.nickname)    #出错位置
        return render_template('note_page.html',note=note,admin_notes=ADMIN_NOTES)

然而问题也正出在这里,当管理员写入新的note之后(即ADMIN_NOTES这个全局变量发生变化之后)重新查询的语句虽然在函数1中执行了(print出的note数量是写入新note之后的数量,)。但当用户根据函数1返回的json跳转到函数2的时候,函数2内就无法正确访问ADMIN_NOTES,准确来说无法访问nnote.author.nickname,其中author是note表用author_id这个外键连接到user表得到的,错误栈如下

Traceback (most recent call last):
  File "C:\Users\MSI-1\Anaconda3\lib\site-packages\flask\app.py", line 1997, in __call__
    return self.wsgi_app(environ, start_response)
  File "C:\Users\MSI-1\Anaconda3\lib\site-packages\flask\app.py", line 1985, in wsgi_app
    response = self.handle_exception(e)
  File "C:\Users\MSI-1\Anaconda3\lib\site-packages\flask\app.py", line 1540, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\MSI-1\Anaconda3\lib\site-packages\flask\_compat.py", line 33, in reraise
    raise value
  File "C:\Users\MSI-1\Anaconda3\lib\site-packages\flask\app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\MSI-1\Anaconda3\lib\site-packages\flask\app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\Users\MSI-1\Anaconda3\lib\site-packages\flask\app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\MSI-1\Anaconda3\lib\site-packages\flask\_compat.py", line 33, in reraise
    raise value
  File "C:\Users\MSI-1\Anaconda3\lib\site-packages\flask\app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\Users\MSI-1\Anaconda3\lib\site-packages\flask\app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "E:\vs\python\AwesomeWebApp\AwesomeWebApp\app\views.py", line 232, in note
    print(nnote.author.nickname)    #let author.id be preloaded
  File "C:\Users\MSI-1\Anaconda3\lib\site-packages\sqlalchemy\orm\attributes.py", line 282, in __get__
    return self.impl.get(instance_state(instance), dict_)
  File "C:\Users\MSI-1\Anaconda3\lib\site-packages\sqlalchemy\orm\attributes.py", line 710, in get
    value = self.callable_(state, passive)
  File "C:\Users\MSI-1\Anaconda3\lib\site-packages\sqlalchemy\orm\strategies.py", line 688, in _load_for_state
    % (orm_util.state_str(state), self.key)
sqlalchemy.orm.exc.DetachedInstanceError: Parent instance <Note at 0x26de5f41198> is not bound to a Session; lazy load operation of attribute 'author' cannot proceed (Background on this error at: http://sqlalche.me/e/bhk3)

sqlalchemy报出detached错误
sqlalchemy.orm.exc.DetachedInstanceError: Parent instance is not bound to a Session; lazy load operation of attribute 'author' cannot proceed (Background on this error at: http://sqlalche.me/e/bhk3)

这该怎么解决?或者还有什么其他方法实现:在我的webapp中,每个页面都要用到同一个一般不会变化的查询结果,为避免每次访问都需查询一次这个一般不会变量,我在views.py中弄了一个全局变量ADMIN_NOTES。而当ADMIN_NOTE会发生变化时,如此时管理员又写入了一个新note,则重新查询数据库获得最新的ADMIN_NOTE的值,尽量减少访问数据库的次数

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2022-09-09 18:36
    关注
    不知道你这个问题是否已经解决, 如果还没有解决的话:

    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 以帮助更多的人 ^-^
    评论

报告相同问题?

悬赏问题

  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 牛顿斯科特系数表表示
  • ¥15 arduino 步进电机
  • ¥20 程序进入HardFault_Handler
  • ¥15 关于#python#的问题:自动化测试