2012-08-02 14 views
5

Utilizziamo la funzione di autoload di sqlalchemy per eseguire il mapping delle colonne per impedire l'hardcoding nel nostro codice.sqlalchemy autoloaded orm persistence

class users(Base): 
    __tablename__ = 'users' 
    __table_args__ = { 
     'autoload': True, 
     'mysql_engine': 'InnoDB', 
     'mysql_charset': 'utf8' 
    } 

C'è un modo per serializzare o di cache autocaricate metadati/ORM in modo da non passare attraverso il processo di caricamento automatico ogni volta che abbiamo bisogno di fare riferimento a nostre classi ORM da altri script/funzioni?

Ho guardato il cecking e il pickle nel becher ma non ho trovato una risposta chiara se è possibile o come farlo.

Idealmente ci eseguire lo script di mappatura autload solo quando ci siamo impegnati modifiche alla nostra struttura del database, ma fare riferimento a una non-autoload/persistent/versione memorizzata nella cache del nostro mappatura database da tutti gli altri script/funzioni,

Tutte le idee?

+0

Perché non fai il contrario: definisci il modello completo in SA. Come effetto collaterale, questo fungerà da controllo del codice sorgente per lo schema del database. * Naturalmente, questo funziona solo se l'applicazione SA ha il controllo principale dei database che si sta lavorando con * – van

+0

lo sviluppo del database viene gestito separatamente nel mio caso, significa che l'applicazione non ha il controllo completo. Tuttavia, ho trovato un modo per decantare i metadati quindi devo solo riflettere tramite connessione al database una volta per creare il pickle, il tempo in cui utilizzo i metadati decapitati per riflettere che richiede una frazione del tempo attraverso la connessione db (vedi sotto). – user1572502

risposta

5

Quello che sto facendo ora è di mettere sott'occhio i metadati dopo aver eseguito il reflection tramite una connessione al database (MySQL) e una volta che un pickle è disponibile usa i metadati decapitati per riflettere sullo schema con i metadati associati a un motore SQLite.

cachefile='orm.p' 
dbfile='database' 
engine_dev = create_engine(#db connect, echo=True) 
engine_meta = create_engine('sqlite:///%s' % dbfile,echo=True) 
Base = declarative_base() 
Base.metadata.bind = engine_dev 
metadata = MetaData(bind=engine_dev) 

# load from pickle 
try: 
    with open(cachefile, 'r') as cache: 
     metadata2 = pickle.load(cache) 
     metadata2.bind = engine_meta 
     cache.close() 
    class Users(Base): 
     __table__ = Table('users', metadata2, autoload=True) 

    print "ORM loaded from pickle" 

# if no pickle, use reflect through database connection  
except: 
    class Users(Base): 
     __table__ = Table('users', metadata, autoload=True) 

print "ORM through database autoload" 

# create metapickle 
metadata.create_all() 
with open(cachefile, 'w') as cache: 
    pickle.dump(metadata, cache) 
    cache.close() 

Eventuali commenti se questo va bene (funziona) o c'è qualcosa che posso migliorare?

+2

probabilmente potresti semplificarlo solo per usare l'unico oggetto MetaData, e anche solo un semplice "se os.path.exists (cachefile)" per determinare se stai annullando o meno. "Tabella ('utenti', metadati, autoload = True)" e tale solo deve essere dichiarata una volta poiché, come hai già visto, salta la riflessione se la tabella è già nel MetaData. – zzzeek

+1

Penso che non sia necessario chiudere un file quando viene usato all'interno di un'istruzione 'with', ma questo non è correlato. Il tuo approccio sembra interessante, funziona come previsto? – jadkik94

Problemi correlati