求助:Flask 开发中的 Sqlite3 的困惑 - V2EX
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
Hualin
V2EX    Python

求助:Flask 开发中的 Sqlite3 的困惑

  •  
  •   Hualin 2013-02-03 21:02:53 +08:00 4895 次点击
    这是一个创建于 4707 天前的主题,其中的信息可能已经有所发展或是发生改变。
    如前,我最近业余时间在写一个网站,遇到如下困惑,请大家帮忙:
    1. 数据库(sqlite3)中的数据类型真的有用吗?我写的网站有几张有十几个 field 的表单有反复提交和显示。之前开发的时候我做了一个 trick 在 template 和 python 响应函数中都用循环来提取 field 中的信息,包括:在数据库中读取,在数据库中写入,在 template 渲染,在template 获取 form 提交。

    昨天我编到,需要从 template 中读取 input form 中的数据来对数据库相应表单进行更新,假设:

    in sqlite3:
    table f1b1 (
    subject_id integer not null primary key,
    status boolean default 0, field01 string default null,

    )
    第 1 条附言    2013-02-04 00:02:15 +08:00
    在template 相应函数部分代码为:
    基本意思就是响应函数根据预定义的检索关键字抓取新提交的表单的value,然后数据库相应内容。底下代码可以无视,反正我写的很烂。

    def save_block(subject_id, block_name):
    ## just update the row
    # if not session.get('logged_in'):
    # abort(401)
    qs = 'update ' + block_name + ' set '
    from rule import fieldTitle
    for fn in fieldTitle[block_name].iterkeys():
    cOntent= fn
    print content, request.form[fn], type(request.form[fn]) ## debug
    qs = qs + fn + '=' + request.form[fn] + ', '
    qs = qs[0: -2] + ' where subject_id=?'
    print qs ## debug
    db = ut.get_db()
    db.execute(qs, [subject_id])
    db.commit()
    flash('The Form sheet has been saved')
    ## update the status
    return redirect(url_for('view_subject', subject_id = subject_id))


    起初经常报出 'No such column name None',因为我之前设置过数据库中初始化,如果没有值就是 null,然后 python 显示此表单,里面的值就成了 None,在传回数据库,它就不认识了。好了,我好不容易发现这个 bug,我小心翼翼的提交的表单的数据(本身全是 None),按照数据库中的内容一一填好,string 是 string,整数是整数,日期是日期。

    后来我发现,我在上面贴的代码,如果我不在 HTML 表单中直接 填入 “XXXXXXX", python 会认为我提交的是一个变量名而不是字符串。似乎不是很智能。我打印出抓取表单的数据类型,全是 unicode。

    所以我需要在响应函数抓取数据后往sql注入新的数据前进行类型转换。好了,困惑出来了:那么我需要在 python 里面再定义一堆数据类型检查表,我觉得相当于把sql里面定义的表再在python里面写一遍。所以我觉得还不如,把sqlite里面的 field 全部定义为 string 算了。

    那么请问你们在写网页的时候后端的数据库的 field 是怎么定义的,逻辑层中数据类型又是怎么检查的?
    15 条回复    1970-01-01 08:00:00 +08:00
    diib
        1
    diib  
       2013-02-03 21:30:43 +08:00
    sqlite3 的数据类型都是基于text的。
    diib
        2
    diib  
       2013-02-03 21:35:49 +08:00
    另外貌似这个帖子没写完?似乎读不懂……
    Hualin
        3
    Hualin  
    OP
       2013-02-03 23:51:13 +08:00
    @diib 对 刚点错啦 马上补上
    yoyicue
        4
    yoyicue  
       2013-02-04 00:08:29 +08:00
    为啥不用 sqlalchemy 和 wtforms 呢?
    Hualin
        6
    Hualin  
    OP
       2013-02-04 00:11:47 +08:00
    @yoyicue 不是选什么数据库的问题,问题出在从 template 获取 request.form['some_keyword'] 的 value 是 unicode, 然后再注入数据库的时候 数据类型的转换不是很智能。

    flask 自己没有完整的数据库逻辑 不像 django 。至少我理解的是这样。
    yoyicue
        7
    yoyicue  
       2013-02-04 00:12:25 +08:00
    我在点击回复的瞬间 猫跳上键盘 敲了个 m,
    Hualin
        8
    Hualin  
    OP
       2013-02-04 00:13:38 +08:00
    @yoyicue well honestly, 我不是很 appreciate 你这样的回答,不解决当前的实际问题。
    yoyicue
        9
    yoyicue  
       2013-02-04 00:15:38 +08:00   1
    @Hualin

    你没理解我的意思, 我没说用什么数据库的问题,
    总之用了 sqlalchemy 和 wtforms 从来没有这个烦恼.
    使用 extensions 也是官方推荐的.
    Hualin
        10
    Hualin  
    OP
       2013-02-04 00:17:55 +08:00
    @yoyicue 好吧 我觉得我需要解决燃眉之急。我还是找找 python unicide 数据类型 有没有比较智能的数据类型转换方法算了。 thx anyway
    yoyicue
        11
    yoyicue  
       2013-02-04 00:18:24 +08:00
    @Hualin 呵呵 那你自己慢慢考虑吧
    人生苦短 用不用 ORM 自己决定
    yegle
        12
    yegle  
       2013-02-04 00:28:27 +08:00   2
    @Hualin

    有一个通用的解决方案是,表只存一个field,把要存的数据保存成dict,json.dumps成字符串保存到数据库里

    为了保证你的代码通用性(sqlite3不满足需求,需要用MySQL怎么办?),保证安全性(『手动拼接SQL是SQL注入万恶之源』),还是用ORM吧。

    另外,如果觉得flask没有好用的数据库逻辑,你总是可以from django.db import models的
    Hualin
        13
    Hualin  
    OP
       2013-02-04 00:44:32 +08:00
    @yegle django 太“强大”了,我还玩不转。
    我就是手动拼接sql 语句的 T.T

    我在想我要不要把数据库里的东西全存成 string 类型,这样我对每个 field 的操作都是 用引号 wrap 一下。反正我也不用 sqlite 单独做什么就是存个东西而已。

    今天才知道 orm ,,,还是后面再学学吧。
    diib
        14
    diib  
       2013-02-04 07:44:18 +08:00 via Android
    不要直接拼sql,如果暂时不用orm,那么就把网页传回来的信息每一个都检查一遍,并转换成对应的数据类型,然后用参数化的方式构建sql语句并执行。虽然繁琐了些。。。
    Hualin
        15
    Hualin  
    OP
       2013-02-05 00:36:22 +08:00
    @diib 的确 我已经开始用 flask-sqlalchemy 真的感谢大家的建议。
    另外 你们开始学开发的时候是怎么知道拼接 sql 很危险?any further reading?
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3210 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 11:05 PVG 19:05 LAX 03:05 JFK 06:05
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86