2012-11-06 20 views
7

'u ekleyip yoksayın ve SQLite docs'u okudum, Stack Overflow üzerinde çeşitli soru ve cevapları ve this thing'u okudum, ancak tam bir cevaba gelmedim.SQLite, orijinal _rowid_

ben SQLite ile INSERT OR IGNORE INTO foo VALUES(...) böyle bir şey yapmak ve orijinal satırın satır kimliğini geri almak için bir yolu yoktur biliyoruz ve buna en yakın INSERT OR REPLACEolacağını ama bu tüm satırı siler ve yeni bir satır ekler ve Böylece yeni bir satırbaşı alır.

Örnek tablo:

sql = sqlite3.connect(":memory:") 
# create database 
sql.execute("INSERT OR IGNORE INTO foo(data) VALUES(?);", ("Some text.",)) 
the_id_of_the_row = None 
for row in sql.execute("SELECT id FROM foo WHERE data = ?", ("Some text.",)): 
    the_id_of_the_row = row[0] 

Ama ideal bir şey gibi görünecektir:: Şu anda

CREATE TABLE foo(
    id INTEGER PRIMARY KEY AUTOINCREMENT, 
    data TEXT 
); 

Yapabileceğim en iyisi nedir

the_id_of_the_row = sql.execute("INSERT OR IGNORE foo(data) VALUES(?)", ("Some text",)).lastrowid 

(okuyun: En verimli) bir tabloya bir satır eklemek ve rowid döndürmek ya da i t zaten var ve sadece rowid olsun? Verimlilik önemlidir, çünkü bu oldukça sık gerçekleşecektir.

INSERT OR IGNORE bir yolu var mı ve göz ardı satır karşılaştırıldı o satırın satır kimliğini döndürür? Bu, bir kesici uç kadar verimli olacağı için harika olurdu. Kaydın kimliğini umursamadığınız durumlar içindir;

+1

"UPDATE ... WHERE ..." yi denediniz mi? – Keith

cevap

6

Benim için en iyi şekilde çalışmanın yolu insert or ignore değerleri ve select satır iki farklı adımda oldu. Her iki seçimi de hızlandırmak ve çiftleri önlemek için data sütununda unique kısıtlaması kullandım. Ben olacağını düşündüğümüz gibi

sql.execute("INSERT OR IGNORE INTO foo(data) VALUES(?);" ("Some text.",)) 
last_row_id = sql.execute("SELECT id FROM foo WHERE data = ?;" ("Some text. ",)) 

select ifadesi olarak yavaş değil. Bu, it seems, SQLite otomatik olarak unique sütunlar için bir dizin oluşturuyor.

1

INSERT OR IGNORE; Hedefin yalnızca bu değerle bazı kayıt olması. Eğer yeni bir rekor takılı olup olmadığını bilmek istiyorsanız

, elle kontrol etmek zorunda:

verimlilik gelince
the_id_of_the_row = None 
for row in sql.execute("SELECT id FROM foo WHERE data = ?", ...): 
    the_id_of_the_row = row[0] 
if the_id_of_the_row is None: 
    c = sql.cursor() 
    c.execute("INSERT INTO foo(data) VALUES(?)", ...) 
    the_id_of_the_row = c.lastrowid 

: SQLite çiftleri için data sütunu kontrol ettiğinde, tam olarak yapmak zorunda SELECT ile yaptığınız sorgunun aynısını yaptınız ve bunu yaptıktan sonra, erişim yolu önbellekte olduğundan performansın bir sorun olmaması gerekir. Her durumda, iki ayrı INSERT/SELECT sorgusunu yürütmek için gerekli değeridir (her iki sırada da, hem kod numaranız hem de kodunuz çalışır, ancak sizinki daha basittir).