2012-06-22 56 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