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
nersle
V2EX  ›  Python

Python Flask-SQLAlchemy 使用疑惑

  •  
  •   nersle · 2015-12-30 08:47:50 +08:00 · 3306 次点击
    这是一个创建于 3255 天前的主题,其中的信息可能已经有所发展或是发生改变。

    使用 Flask-SQLAlchemy 时遇到一个很奇怪的问题,使用下面的代码插入数据库会成功:
    report = Report(tid=vulId, vulURL=vulURL, homeTitle=homeTitle, homeLink=homeLink, DBInfo=DBInfo,vulId=vulParId, UserLists=UserLists, dbsLists=dbsLists, content=content)
    db.session.add(report)

    奇怪的是 Mysql 中确实插入成功了,程序会跳转到 /report/view/vulId
    return redirect("/report/view/"+str(vulId))

    在 viewReport 函数中使用如下代码查询后返回 None :
    report = Report.query.filter(Report.tid==vulId).first()

    ,但是此时如果在 model.py 的 main 函数中执行
    report = Report.query.filter(Report.tid==vulId).first()

    却会返回正确数据,此时再在 viewReport 函数中执行就不为空了。多次测试发现失败概率在 30%左右,现在不知道该怎么定位错误,麻烦各位指教!

    相关代码

    @app.route("/report/view/<int:vulId>", methods=["GET"])
    def viewReport(vulId=-1):
    if vulId < 0:
    return redirect("/vul/list")

    title = "Report-{}".format(vulId)
    report = Report.query.filter(Report.tid==vulId).first()
    
    if report == None:  
        reUrl = request.headers.get("Referer")
        return redirect(reUrl)  
    
    return render_template("report.html", title=title, report=report)
    

    @app.route("/report/make/<int:vulId>", methods=["GET", "POST"])
    def makeReport(vulId=-1):
    if vulId < 0:
    return redirect("/vul/list")

    form = ReportForm()
    # print form.errors
    if form.validate_on_submit():
        # tid = form.tid.data
        vulURL = form.vulURL.data
        homeTitle = form.homeTitle.data
        homeLink = form.homeLink.data
        DBInfo = form.DBInfo.data
        vulParId = form.vulId.data
        UserLists = form.UserLists.data
        dbsLists = form.dbsLists.data
        content = form.content.data
    
        report = Report(tid=vulId, vulURL=vulURL, homeTitle=homeTitle, homeLink=homeLink, DBInfo=DBInfo,
            vulId=vulParId, UserLists=UserLists, dbsLists=dbsLists, content=content) 
    
        db.session.add(report) 
    
        vul = Task.query.filter(Task.tid==vulId).first()
        vul.detectFlag = 2   
        db.session.commit()  
    
        return redirect("/report/view/"+str(vulId))
    else:
        title = "Report-{}".format(vulId)
        vul = Task.query.filter(Task.tid==vulId).first()  
    
        vulTitle = ""
        pageTitle = ""
        try:
            pageTitle = httpHandle.getTitle(vul.url)
        except Exception, e:
            pageTitle = "Get title error!{}".format(e)
    
        encodeType = chardet.detect(pageTitle) 
        if encodeType["encoding"] == "GB2312":
            vulTitle =  pageTitle.decode("gb2312",'ignore')
        else:
            vulTitle = pageTitle.decode("utf-8",'ignore') 
    
        form.vulURL.process_data(vul.getURL())
        form.content.process_data(vul.getRawData()) 
        return render_template("makeReport.html", title=title, vul=vul, vulTitle=vulTitle, form=form)
    
    17 条回复    2015-12-30 16:55:47 +08:00
    janxin
        1
    janxin  
       2015-12-30 09:16:53 +08:00
    db.session.commit()试一下?
    saberlion
        2
    saberlion  
       2015-12-30 10:10:20 +08:00
    sqlalchemy 的 debug 打开有真相
    lixiaohan
        3
    lixiaohan  
       2015-12-30 10:39:38 +08:00
    你要先 commit db.session.commit()
    florije
        4
    florije  
       2015-12-30 10:51:02 +08:00
    还是 debug 看信息吧,一般会显示出来所有的生成 sql 命令,看下插入或者查找失败的失败的 sql 是哪里不对,另, ls 小伙伴们人家 LZ 已经写了 commit 了……
    janxin
        5
    janxin  
       2015-12-30 11:27:25 +08:00
    @florije 确实没注意到下面的具体代码里有,我的锅
    nersle
        6
    nersle  
    OP
       2015-12-30 12:07:34 +08:00
    @saberlion MySQL 都插入成功了呢,只是需要在 model.py 的 main 函数中执行
    ```report = Report.query.filter(Report.tid==vulId).first()
    再在 views.py 中运行
    ```report = Report.query.filter(Report.tid==vulId).first()
    才会成功,求解
    nersle
        7
    nersle  
    OP
       2015-12-30 12:08:05 +08:00
    @florije Mysql 插入成功了....确实有数据
    tanywei
        8
    tanywei  
       2015-12-30 12:28:27 +08:00
    这种都是 session 的问题吧, 先 flush 一把看看。
    nersle
        9
    nersle  
    OP
       2015-12-30 12:59:45 +08:00
    @tanywei 怎么 flush ? commit 还不行么?
    nersle
        10
    nersle  
    OP
       2015-12-30 13:08:31 +08:00
    刚测试发现,或者重新运行 Flask 应用也行,真是好奇怪,修改一条记录,就得重新运行一次
    tanywei
        11
    tanywei  
       2015-12-30 13:38:07 +08:00
    flask sqlalchemy scoped_session 搜搜看。
    janxin
        12
    janxin  
       2015-12-30 13:57:24 +08:00
    你先试试
    ```python
    app.config['SQLALCHEMY_ECHO'] = True
    app.config['SQLALCHEMY_RECORD_QUERIES'] = True
    ```
    看一下输出
    nersle
        13
    nersle  
    OP
       2015-12-30 15:35:50 +08:00
    @janxin 配置了,没有用, SQL 语句也没有问题,确实插入数据库了
    blueegg
        14
    blueegg  
       2015-12-30 16:00:51 +08:00
    我晕,终于可以回复了。加这一句试试 db.session.remove()
    alexapollo
        16
    alexapollo  
       2015-12-30 16:38:55 +08:00
    遇到这种坑的时候非常庆幸自己是手动管理的……
    florije
        17
    florije  
       2015-12-30 16:55:47 +08:00
    能切到 sqlite 然后把相关部分代码整理下放 github 上吗?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3511 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 04:49 · PVG 12:49 · LAX 20:49 · JFK 23:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.