2017-01-13 35 views
0

URLからXMLを抜き取り、解析してsqlite3データベースに格納しようとしています。 Coddeはこれまで:エラーを取得Python、XMLデータをsqlite3に挿入

#!/usr/bin/env python 

from urllib2 import urlopen 
import gc 
import xml.etree.ElementTree as ET 
import sqlite3 

rosetta_url = ("https://boinc.bakerlab.org/rosetta/team_email_list.php?teamid=12575&account_key=Y&xml=1") 

root = ET.parse(urlopen(rosetta_url)).getroot() 
cpids = [el.text for el in root.findall('.//user/cpid')] 
print cpids 

conn = sqlite3.connect("GridcoinTeam.db") 
c = conn.cursor() 
c.execute('''CREATE TABLE IF NOT EXISTS GRIDCOINTEAM (cpid TEXT)''') 
c.executemany("INSERT INTO GRIDCOINTEAM VALUES (?);", cpids) 
conn.commit()  
conn.close() 

conn = sqlite3.connect("GridcoinTeam.db") 
c = conn.cursor() 
cpids = c.execute('select cpid from GRIDCOINTEAM').fetchall() 
conn.close() 

print cpids 

gc.collect() 

イム:

Incorrect number of bindings supplied. The current statement uses 1, and there are 32 supplied. 

私は

c.executemany("INSERT INTO GRIDCOINTEAM VALUES (?);", (cpids,)) 

に変更することにより、挿入タプルを作ってみましたが、それはちょうど与える:

Incorrect number of bindings supplied. The current statement uses 1, and there are 3289 supplied. 

XML抽出は[' 5da243d1f47b7852d372c51d6ee660d7 '、' 5a6d18b942518aca60833401e70b75b1 '、' 527ab53f75164864b74a89f3db6986b8 ']がありますが、数千のエントリがあります。

ありがとうございました。

+1

XMLデータのダウンロードが問題とは何の関係もありません。 print行で証明されているように、 'cpids'リストは正しく定義されています。次回は、問題を関連する部分に縮小しようとしてください。 –

答えて

1
あなたは1行には、このように複数の行の代わりに、複数の列を挿入する必要が

cpids = [el.text for el in root.findall('.//user/cpid')] 
cpids = zip(*[iter(cpids)]*1) 
print cpids 
+0

ありがとう、私はそのリスト形式を修正する方法を知りませんでした、それは感謝します。 – Scalextrix

0

問題が

c.executemany("INSERT INTO GRIDCOINTEAM VALUES (?);", cpids) 

にあるこのexecutemanyはタプルのリストを期待していますが、リストを渡します弦のどのようなコードを効率的に行うことは次のとおりです。文字列をアンロードし、そして一つだけをしたいのに対し、あなたに32+のparamsを与える

for entry in cpids: 
    c.execute("INSERT INTO GRIDCOINTEAM VALUES (?);", *entry) 

entry前に星、。

あなたのGRIDCOINTEAMテーブルスキーマを知る必要があることを修正するために、あなたが1つの列だけを持つテーブルを持っていて、それを挿入したい場合、あなたはおそらくこれを行うことができます:executemanyとは対照的に

for entry in cpids: 
    c.execute("INSERT INTO GRIDCOINTEAM VALUES (?)", entry) 

を、executeは1つのparamとして各パラメータを取りません - ここでアンロードなしタプルとリストを。

は、別の方法としては、 executemanyを使用してに頼ることはできますが、その後、タプルまたは発電機にあなたの文字列の一つ一つをラップする必要があるだろう:

c.executemany("INSERT INTO GRIDCOINTEAM VALUES (?);", [(i,) for i in cpids]) 
関連する問題