2010-02-15 16 views

risposta

4

Purtroppo non sono a conoscenza di una buona risposta generale per questo. Alcuni dbapi (psycopg2 per esempio) supportano l'esecuzione di molte affermazioni alla volta. Se i file non sono enormi, puoi semplicemente caricarli in una stringa ed eseguirli su una connessione. Per gli altri, proverei ad usare un client da riga di comando per quel db e inserire i dati in quello usando il modulo subprocess.

Se questi approcci non sono accettabili, è necessario procedere e implementare un parser SQL piccolo in grado di suddividere il file in istruzioni separate. Questo è davvero difficile da ottenere corretto al 100%, poiché dovrai considerare le regole di escape letterale specifiche del dialetto del database, il set di caratteri utilizzato, tutte le opzioni di configurazione del database che influiscono sull'analisi letterale (ad esempio PostgreSQL standard_conforming_strings).

Se hai solo bisogno di ottenere questo 99,9% corretto, allora qualche magia di regexp dovrebbe farti arrivare quasi tutto lì.

4

Se si utilizza sqlite3 ha un'estensione utile per dbapi chiamato conn.executescript (str), l'ho collegato tramite qualcosa di simile e sembrava funzionare: (Non tutto il contesto è mostrato ma dovrebbe essere abbastanza per ottenere la deriva)

def init_from_script(script): 
    Base.metadata.drop_all(db_engine) 
    Base.metadata.create_all(db_engine)  

    # HACK ALERT: we can do this using sqlite3 low level api, then reopen session. 
    f = open(script) 
    script_str = f.read().strip() 
    global db_session 
    db_session.close() 
    import sqlite3 
    conn = sqlite3.connect(db_file_name) 
    conn.executescript(script_str) 
    conn.commit() 

    db_session = Session() 

Questo puro male mi chiedo? Ho cercato invano un equivalente sqlalchemy "puro", forse che potrebbe essere aggiunto alla libreria, qualcosa come db_session.execute_script (file_name)? Spero che db_session funzionerà bene dopo tutto questo (cioè non c'è bisogno di riavviare il motore) ma non sono ancora sicuro ... ulteriori ricerche necessarie (cioè abbiamo bisogno di ottenere un nuovo motore o solo una sessione dopo essere tornati alle spalle di sqlalchemy ?)

FYI sqlite3 include una routine correlato: sqlite3.complete_statement (SQL) se si tira il proprio parser ...

1

sono stato in grado di eseguire sql file di schema utilizzando SQLAlchemy pura e alcune manipolazioni di stringhe. Sicuramente non è un approccio elegante, ma funziona.

# Open the .sql file 
    sql_file = open(<file.sql>,'r') 

    # Create an empty command string 
    sql_command = '' 

    # Iterate over all lines in the sql file 
    for line in sql_file: 
     # Ignore comented lines 
     if not line.startswith('--') and line.strip('\n'): 
      # Append line to the command string 
      sql_command += line.strip('\n') 

      # If the command string ends with ';', it is a full statement 
      if sql_command.endswith(';'): 
       # Try to execute statemente and commit it 
       try: 
        session.execute(text(sql_command)) 
        session.commit() 

       # Assert in case of error 
       except: 
        print('Ops') 

       # Finally, clear command string 
       finally: 
        sql_command = '' 

Iterizza su tutte le righe in un file .sql ignorando le righe commentate. Quindi concatena le righe che formano un'istruzione completa e tenta di eseguire l'istruzione. Hai solo bisogno di un gestore di file e un oggetto di sessione.