2012-01-26 1 views
8

Ho questo codice:Come posso verificare se un inserto ha avuto successo con MySQLdb in Python?

cursor = conn.cursor() 
cursor.execute(("insert into new_files (videos_id, filename, " 
       "is_processing) values (%s,%s,1)"), (id, filename)) 
logging.warn("%d", cursor.rowcount) 
if (cursor.rowcount == 1): 
    logging.info("inserted values %d, %s", id, filename) 
else: 
    logging.warn("failed to insert values %d, %s", id, filename) 
cursor.close() 

divertimento come è, cursor.rowcount è sempre uno, anche se ho aggiornato il mio database per rendere la videos_id una chiave univoca. Cioè, l'inserto fallisce perché nei miei test comparirà lo stesso videos_id (e quando controllo il database, non è stato inserito nulla). ma per qualsiasi motivo, il rowcount è sempre 1 - anche l'logging.warn ho sputa fuori un rowcount 1.

Quindi, la domanda:
Posso usare rowcount di capire se un inserto andato a buon fine? Se è così, cosa sto facendo (presumibilmente) sbagliato? altrimenti, come posso controllare se un inserto è andato bene?

risposta

22

Il codice non viene eseguito dopo le modifiche (le modifiche vengono annullate). Cioè si dovrebbe aggiungere la seguente riga dopo cursor.execute:

conn.commit() 

inserto Impossibile getterà MySQLdb.IntegrityError, così si dovrebbe essere pronti a prenderlo.

Così, il codice dovrebbe essere simile:

sql_insert = """insert into new_files (videos_id, filename, is_processing) 
values (%s,%s,1)""" 

cursor = conn.cursor() 
try: 
    affected_count = cursor.execute(sql_insert, (id, filename)) 
    conn.commit() 
    logging.warn("%d", affected_count) 
    logging.info("inserted values %d, %s", id, filename) 
except MySQLdb.IntegrityError: 
    logging.warn("failed to insert values %d, %s", id, filename) 
finally: 
    cursor.close() 
+0

Sei un campione, grazie – bharal

+1

Domanda. Cosa succede se si inseriscono 500 record alla volta prima di eseguire il commit (tramite una query lunga o più inserimenti discreti)? cioè sto solo lavorando ogni 500 dischi; se uno di questi record fallisce, come posso stampare solo quel record e continuare a inserire gli altri. – gunslingor

+0

@ user3656612 dipende dal motivo per cui falliscono. Se il problema è con la rottura di alcuni vincoli, è possibile utilizzare INSERISCI IGNORE o INSERT ... ON DUPLICATE KEY UPDATE. Se si tratta di un errore di connessione, non puoi fare nulla. Se si tratta di un errore di sintassi, dovresti prendere in considerazione la possibilità di correggere i bug nella tua applicazione. – newtover

1

Se l'inserto non funziona, otterrai un'eccezione sollevata o qualcuno urlerà o cadrai dalla sedia.

+0

Odio quando cado dalla sedia. –

+0

c'è un modo elegante per catturare tutte e tre le possibilità a livello di programmazione? – bharal

+1

try: Qualcosa: tranne Exception, e: print "it failed", str (e) - quindi metti quello che vuoi dove è "Something". – synthesizerpatel

1

Come utilizzare un blocco try/catch anziché considerare il conteggio delle righe. Se rileva un'eccezione, c'è un problema; altrimenti, nessun problema.

+0

Sono un po 'nuovo in Python (e in mysqldb), qualsiasi possibilità si possa spendere in un esempio - cioè quale eccezione prendo nel blocco catch try? – bharal

2

io non ho abbastanza reputazione per fare un commento, ma qui è una nota importante:

E 'anche possibile per execute() fallire silenziosamente se non si effettua il commit dopo la chiamata. Vale a dire, le tabelle MyISAM non richiedono il commit, ma quelle di InnoDB.