2012-06-22 59 views
2

我遇到了将值插入SQLite数据库的问题。我从挪威议会网站data.stortinget.no下载的数据。我得到的错误是:sqlite3.OperationalError:无法识别的标记:“01T00”sqlite3.OperationalError:无法识别的令牌:“01T00”Python日期戳

这是在错误发生的方法:(我知道在此摘录压痕错误)

def get_perioder(cur): 
DOK = "stortingsperioder" 
try: 
    page = urllib2.urlopen(SITE+DOK) 
except: 
    print "Failed to fetch item "+DOK 
if page: 
    tree = ElementTree.parse(page) 
    root = tree.getroot() 
    top = list(root)[2] 
    elements = list(top) 
    for el in elements: 
     fra = el.find('{http://data.stortinget.no}fra').text 
     per_id = el.find('{http://data.stortinget.no}id').text 
     til = el.find('{http://data.stortinget.no}til').text 
     print "id: %s fra: %s til: %s" % (per_id, fra, til) 
     cur.execute("INSERT INTO perioder(fra, id, til) VALUES(%s,%s,%s)" % (fra, per_id, til)) 
else: 
    print "Could not load page: "+DOK 

消息通过上面的打印打印刚刚在上面cur.execute是: id:2009-2013 fra:2009-10-01T00:00:00 til:2013-09-30T23:59:59 整个错误跟踪是:

BigMac:Stortingsdata ola$ python getBasicData.py 
id: 2009-2013 fra: 2009-10-01T00:00:00 til: 2013-09-30T23:59:59 
Traceback (most recent call last): 
    File "getBasicData.py", line 169, in <module> 
    get_perioder(cur) 
    File "getBasicData.py", line 26, in get_perioder 
    cur.execute("INSERT INTO perioder(fra, id, til) VALUES(%s,%s,%s)" % (fra, per_id, til)) 
sqlite3.OperationalError: unrecognized token: "01T00" 

我提到的SQLite手册,似乎格式我我支持,所以我想知道问题来自哪里。

+1

您不通过带引号的日期INSERT INTO perioder(fra,id,til)VALUES('%s',%s,'%s')'? – Jones

+1

你插入的是'VALUES(2009-2013,2009-10-01T00:00:00,2013-09-30T23:59:59)''。你明白为什么这是错的,对吧?你刚刚插入了相当于'VALUES(-4,-1-01T00:00:00,2004-30T23:59:59)',这显然是一个语法错误,因为'01T00'不能从-1中减去'。只需正确使用'execute'而不是进行字符串插值。 –

+0

现在我明白了。我认为%s增加了所需的引号,但我错了。谢谢你们的帮助,它现在正在工作。我运行代码时出现另一个问题。它执行第一种方法,但不添加额外的数据。我可以将游标传递给方法并添加数据,还是需要更多的游标? (该程序没有任何并发​​性) – olovholm

回答

7

正确的方法是使用参数化查询。
例子:

cur.execute("""INSERT INTO perioder(fra, id, til) 
       VALUES (?,?,?);""", (fra, per_id, til)) 

有特定参数的“风格”为每个数据库驱动程序。
在SQLite的情况下,参数风格是?

另请注意,参数值作为第二个参数传递给​​。
使用字符串插值会使您容易遇到各种引用问题(如带给您的引用问题)以及SQL注入攻击的可能性。请致电the DB-APIdatabase programming wiki

+0

如果我插入的表有很多字段(远远超过3),是否有更好的方法来做到这一点? –

+0

当然。您没有指定那样的列名称。这个语法也是有效的:'INSERT INTO your_table VALUES(... <你的参数在这里> ...);'。你可以动态生成参数占位符。有关第二步的信息,请参阅此答案http://stackoverflow.com/a/2253879/42346。 – bernie