2015-07-19 9 views
5

Ho i miei dati caricati da file excel ed organizzati per quanto pitone dict dove ogni chiave è il nome della tabella del database e il suo valore è definito come la lista dei dizionari (le righe)Come caricare i dati in tabelle di database esistenti, usando sqlalchemy?

system_data = {table_name1:[{'col_1':val1, 'col2': val1...}, 
          {'col_1':val2, 'col2': val2..}..],  
       table_name2:[{},{}..],[{},{}..]..} 

Questi dati devono essere caricati in esistenti database durante il prelievo di chiavi table_names e valori da system_data.

Inoltre, utilizzo la lista order_table che ho creato in ordine specifico per evitare problemi con FK durante il caricamento dei dati.

Ecco il codice (una delle versioni 1000 che ho provato):

from sqlalchemy import create_engine 
from sqlalchemy.sql import insert 

def alchemy_load(): 
    system_data = load_current_system_data() 
    engine = create_engine('mysql+pymysql://username:[email protected]/my_db') 
    conn = engine.connect() 
    for table_name in ordered_tables: 
     conn.execute(insert(table_name, system_data[table_name])) 
    print("System's Data successfully loaded into Database!") 

Questa funzione produrrà un errore seguente:

"TypeError: 'method' object is not iterable" 

ho sprecato quasi tutto il giorno su questo roba (((

Tutti gli esempi in linea descrivono la situazione in cui un utente utilizza MetaData e crea le proprie tabelle ... Non c'è nulla su come aggiungere effettivamente dati a tabelle esistenti.

C'è una soluzione al mio problema usando la libreria "dataset".

Il codice:

import dataset 

def current_data(): 
    db = dataset.connect(url='mysql+pymysql://user:[email protected]/my_db') 
    system_data = load_current_system_data() 

    for table_name in ordered_tables: 
     db[table_name].insert_many(system_data[table_name]) 
    print("System's Data successfully loaded into Database!") 

MA, non ho idea di come implementare questo codice utilizzando sqlalchemy ...

Qualsiasi aiuto sarà apprezzato.

+0

Si dovrebbe guardare agli esempi che utilizzano gli oggetti della tabella SQLalchemy sullo stack overflow. –

+0

Già fatto questo, ci sono un sacco di esempi "statici", dove si crea una tabella e quindi si caricano i dati. Inoltre ci sono decine di tutorial "copia/incollati" su Internet, che sono in realtà gli stessi. Penso di poter implementare questo utilizzando l'API del driver diretto, come MySQLdb o PyMySQL ... Ma come posso farlo funzionare con SQLalchemy? Potresti fornire uno snippet di codice o semplicemente correggere il mio codice? Grazie. – bravoelf

+0

se hai dati csv può essere facilmente portato in mysql. se deve essere in sqlalchemy, si crea una nicchia di aiuto più piccola. così è la condizione di coloro che usano orms e sono bloccati nella loro trappola di colla. – Drew

risposta

4

Una possibile soluzione usando SQLAlchemymetadata sarebbe andata così:

In [7]: 

from sqlalchemy.schema import MetaData 
meta = MetaData() 
meta.reflect(bind=engine) 

In [20]: 

for t in meta.tables: 
    for x in engine.execute(meta.tables[t].select()): 
     print x 
(1, u'one') 
(2, u'two') 
(1, 1, 1) 
(2, 1, 2) 
(3, 2, 0) 
(4, 2, 4) 

(. Io uso selezionare invece di inserimento e applicarlo a un database stupido quello che ho per le prove)

spero che aiuta.

MODIFICA: Dopo i commenti, aggiungo qualche chiarimento.

In MetaData(), tables è un dizionario delle tabelle nello schema. Il dizionario va sotto il nome della tabella, ed è in realtà molto simile al dizionario nel tuo codice. Si potrebbe iterare i metadati come questo,

for table_name, table in meta.tables.items(): 
    for x in engine.execute(table.select()): 
     print x 

o, cercando di adattarlo nel codice, si può solo fare qualcosa di simile,

for table_name in ordered_tables: 
    conn.execute(meta.tables[table_name].insert_many(system_data[table_name])) 
+0

Fantastico !!! Mi hai dato la via ... Ieri ho letto sulla classe dei metadati in SA, ma non sono sicuro di poter passare la stringa table_name ad essa. Controllalo anche – bravoelf

+0

Non sono sicuro di aver capito completamente il tuo commento ma ho aggiornato la risposta cercando di chiarire. – lrnzcig

+0

Grazie. Quello che ho cercato di dire, non ho capito chiaramente "come e dove" passare la stringa nome_tabella. Ora posso vedere che meta.tables [table_name string] lo accetta. Il problema è che sono nuovo ai concetti OOP (specialmente con Python) e SQLAlchemy. Per questo motivo alcune delle mie domande potrebbero sembrare troppo stupide per gli altri. Sto ancora lavorando sodo per migliorare le mie capacità e imparare più cose. Grazie ancora per il tuo tempo e la tua risposta. – bravoelf

0

Quindi, ecco il codice finale (molte grazie a Irnzcig per l'orientamento e per me stesso per una rilettura approfondita dei documenti ufficiali SA^_ ^).

from sqlalchemy import create_engine, MetaData 
# from myplace import load_current_system_data() and other relevant functions 

def alchemy_current(): 
    system_data = load_current_system_data() 
    engine = create_engine('mysql+pymysql://user:[email protected]/your_db_name') 
    meta = MetaData() 
    meta.reflect(bind=engine) 
    conn = engine.connect() 
    for table_name in ordered_tables: 
     conn.execute(meta.tables[table_name].insert().values(system_data[table_name])) 
    conn.close() 
    # engine.dispose() 

    print("System's Data successfully loaded into Database!") 

Tutto questo dovrebbe funzionare, partendo dal presupposto che uno ha:

1. Existing mysql database. 
    2. An organized data as I've described prior in this question. 
    3. An ordered `table_name_list` in order to keep referential integrity and avoid FK problems. 

Nel caso qualcuno hanno una "consigli di miglioramento", sarò contento di sentire.

Ivan.

Problemi correlati