2011-11-11 11 views
5

Sto lavorando con un db remoto per importare dati nel db del mio Django proyect.Esecuzione di query diverse usando mysql-python

Con l'aiuto di MySQLdb Sono riuscito con facilità per creare una funzione di importazione come la seguente:

def connect_and_get_data(useful_string): 
    CONNECTION = MySQLdb.connect(host=..., port=..., 
           user=..., passwd=..., db=..., 
           cursorclass=MySQLdb.cursors.DictCursor, 
           charset = "utf8") 
    cursor = CONNECTION.cursor() 
    cursor.execute("SELECT ... FROM ... WHERE ... AND some_field=%s", (useful_string)) 
    result = cursor.fetchall() 
    cursor.close() 

Molto contento di questo, funziona come previsto.

Ma continuando con il codice, ho notato che a volte ho bisogno di connettermi nuovamente al db, per eseguire altre query diverse.

La prima idea era abbastanza logico, a me: per ogni query avrò bisogno, definire una funzione che chiama connect_and_get_data con la query passato come parametro ... qualcosa di simile:

def get_data_about_first_amazing_topic(useful_string): 
    query = "SELECT ... FROM ... WHERE ... AND some_field=%s" %(useful_string) 
    connect_and_get_data(query) 
    ... 

def get_data_about_second_amazing_topic(other_useful_string): 
    query = "SELECT ... FROM ... WHERE ... AND some_field=%s" %(other_useful_string) 
    connect_and_get_data(query) 
    ... 

con questo modifiche connect_and_get_data:

def connect_and_get_data(query): 
    ... 
    cursor.execute(query) 
    ... 

Come già immaginare, questa soluzione viene a mancare. La risposta di

lettura mluebke alla domanda python mysql fetch query

"Sei il passaggio di argomenti alla funzione di esecuzione, non fare python stringa di sostituzione"

Capii subito dove ho sbagliato; ma sento ancora che manca qualcosa: ho provato diverse soluzioni, ma sono decisamente insoddisfatto di tutte loro.

C'è una "buona" modo per incapsulare la mia funzione connect_and_get_data(query), al fine di servire me come voglio, o sono totalmente nel percorso di sbagliato in questo?

Quali sono considerate "best practice" in questa situazione?

risposta

6

Penso che questo sia quello che stai cercando.

def connect_and_get_data(query, data): 
    ... 
    cursor.execute(query, data) 
    ... 

def get_data_about_first_amazing_topic(useful_string): 
    query = "SELECT ... FROM ... WHERE ... AND some_field=%s" 
    connect_and_get_data(query, ("one","two","three")) 
    ... 

Ma, se si sta andando ad essere fare diverse query in fretta, sarebbe meglio riutilizzare la connessione, dal fare troppe connessioni può perdere tempo.

... 
CONNECTION = MySQLdb.connect(host=..., port=..., 
          user=..., passwd=..., db=..., 
          cursorclass=MySQLdb.cursors.DictCursor, 
          charset = "utf8") 
cursor = CONNECTION.cursor() 
cursor.execute("SELECT ... FROM ... WHERE ... AND some_field=%s", ("first", "amazing", "topic")) 
first_result = cursor.fetchall() 

cursor.execute("SELECT ... FROM ... WHERE ... AND some_field=%s", (("first", "amazing", "topic"))) 
second_result = cursor.fetchall() 

cursor.close() 
... 

Questo renderà il vostro codice molto più efficiente.

+0

Sì ... Hai ragione! Sto andando in questa direzione ... Ma cosa succede se ho bisogno di due _useful_strings_ nella mia domanda? ciò trasformerebbe 'data' in un array di argomenti ... giusto? e come reagirà cursor.execute durante la ricezione di un array di stringhe? mmm ... – dolma33

+1

Puoi usare una tupla (una sequenza simile a un array) come secondo parametro per 'connect_and_get_data'. 'cursor.execute' accetta le tuple come secondo parametro. Le tuple sono solo una sequenza di elementi circondati da parentesi, ad es. '("Uno", "due", "tre")'. Infatti, se guardi il tuo codice, puoi vedere '(useful_string)' tra parentesi come argomento per 'execute()'. – Kylos

+0

Non riesco a riutilizzare la mia connessione per molte domande: sfortunatamente, il db remoto giace su una macchina con una connessione veramente slooow (meno di 10k) e super-instabile (lavorare su un'isola nel mezzo del pacifico ha i suoi svantaggi, e uno di questi è la connessione satellitare lenta) ... quindi devo avere connessioni db "atomiche" corte e leggere ... – dolma33

Problemi correlati