2013-06-18 19 views
11

Bir sözlükten adlandırılmış parametreleri kullanarak bir veritabanına veri eklemeye çalışıyorum. Bunun basit bir SQL deyimi ile çalışıyorum.python sqlite insert adlandırılmış parametreler veya null

SQL = "INSERT INTO status (location, arrival, departure) VALUES (:location, :arrival,:departure)" 
dict = {'location': 'somewhere', 'arrival': '1000', 'departure': '1001'} 
c.execute(SQL,dict) 

Yerini bir yere, 1000 giriş sütununa ve 1001 çıkış sütununa ekler.

Gerçekte sahip olduğum veriler konum içerecektir, ancak varış veya kalkış içerebilir veya her ikisine birden sahip olmayabilir (bu durumda ya hiçbir şey veya NULL tabloya gidebilir). Bu durumda, ben sqlite3.ProgrammingError olsun: Aslında olacak

c.execute(SQL,defaultdict(str,dict)) 

işler biraz daha karışık hale getirmek için: Ben defaultdict kullanarak bu sorunu giderebilirsiniz 2.

bağlanma için bir değer arz etmedi Varış veya ayrılış ile birden fazla konum içeren sözlüklerin listesi.

({'location': 'place1', 'departure': '1000'}, 
    {'location': 'palce2', 'arrival': '1010'}, 
    {'location': 'place2', 'departure': '1001'}) 

ve ben ancak şimdi defaultdict kullanamaz c.executemany ile bu çalıştırmak mümkün istiyorum.

Listedeki her sözlükte dolaşabilir ve birçok c.execute deyimini çalıştırabilirim, ancak yürütme işlemi yapmak için daha uygun bir yöntem gibi görünüyor.

Kolaylık sağlamak için bu örneği basitleştirdim, gerçek verilerin sözlükte çok daha fazla girişi var ve bunu bir JSON metin dosyasından yapıyorum.

Bunu nasıl yapabileceğime dair herhangi bir öneriniz var mı?

cevap

12

Kullanım None eklemek için NULL:

dict = {'location': 'somewhere', 'arrival': '1000', 'departure': None} 
Sen executemany() ile bu kullanmak için bir varsayılan sözlüğü ve bir jeneratör kullanabilirsiniz

:

defaults = {'location': '', 'arrival': None, 'departure': None} 

c.executemany(SQL, ({k: d.get(k, defaults[k]) for k in defaults} for d in your_list_of_dictionaries) 
+0

Teşekkür Martin

Aşağıdaki çalışma örneği (Python 3.4.3) noktasını gösterir. Bu sorunla karşılaşan herkes için, varsayılan sözlüğün, her zaman söz konusu öğeye sahip olsa bile, her olası öğeye bir giriş içermesi gerekir. Ayrıca, executemany hattında eksik bir son yakın ayraç var. – user2497185

0

bu soruna basit bir çözüm olduğunu should çoğu durumda uygulanabilir olmak; sadeceexecutemanyyerinedict listesinindefaultdictlistesini geçmektedir. Eğer defaultdict olarak sıfırdan sıra inşa Başka bir deyişle

, bunun yerine sözlükleri olarak inşa doğrudan komuta executemany için defaultdict satırların listesini iletmek ve daha sonra executemany kullanmadan önce durumu yama olabilir. Eğer çalıştırırsanız

import sqlite3 
from collections import defaultdict 
# initialization 
db = sqlite3.connect(':memory:') 
c = db.cursor() 
c.execute("CREATE TABLE status(location TEXT, arrival TEXT, departure TEXT)") 
SQL = "INSERT INTO status VALUES (:location, :arrival, :departure)" 
# build each row as a defaultdict 
f = lambda:None # use str if you prefer 
row1 = defaultdict(f,{'location':'place1', 'departure':'1000'}) 
row2 = defaultdict(f,{'location':'place2', 'arrival':'1010'}) 
rows = (row1, row2) 
# insert rows, executemany can be safely used without additional code 
c.executemany(SQL, rows) 
db.commit() 
# print result 
c.execute("SELECT * FROM status") 
print(list(zip(*c.description))[0]) 
for r in c.fetchall(): 
    print(r) 
db.close() 

, bu yazdırır: - işleri

('location', 'arrival', 'departure') 
('place1', None, '1000') # None in Python maps to NULL in sqlite3 
('place2', '1010', None) 
İlgili konular