2012-08-02 59 views
5

Estamos utilizando la característica de autocarga de sqlalchemy para hacer mapeo de columna para evitar la codificación rígida en nuestro código.sqlalchemy persistencia de orm automática

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

¿Hay una manera de serializar o caché de metadatos autocargado/ORMS así que no tenemos que pasar por el proceso de carga automática cada vez que tenemos que hacer referencia a las clases de ORM de otros scripts/funciones?

He examinado el almacenamiento en memoria caché y el encurtido del vaso pero no he encontrado una respuesta clara si es posible o cómo hacerlo.

Lo ideal sería que ejecute el script de mapeo autload sólo cuando hemos confirmado cambios a nuestra estructura de base de datos pero hacen referencia a un no-carga automática/versión persistente/caché de nuestra cartografía de base de datos de todos los otros scripts/funciones,

¿Alguna idea?

+0

¿Por qué no hacer al revés: definir el modelo completo en SA. Como efecto secundario, esto actuará como su control de origen para el esquema de la base de datos. * Por supuesto, esto solo funciona si su aplicación SA tiene el control principal de las bases de datos con las que está trabajando * El desarrollo de la base de datos de – van

+0

se maneja por separado en mi caso, significa que la aplicación no tiene control total. Sin embargo, encontré una forma de recortar los metadatos, así que solo necesito reflejar a través de la conexión de la base de datos una vez para crear el pickle, el tiempo que uso los meta datos para reflejar lo que toma una fracción del tiempo a través de la conexión db (ver a continuación). – user1572502

Respuesta

5

Lo que estoy haciendo ahora es recortar los metadatos después de ejecutar el reflejo a través de una conexión de base de datos (MySQL) y una vez que un pickle está disponible use esos metadatos conservados para reflejar el esquema con los metadatos vinculados a un motor 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() 

¿Algún comentario si está bien (funciona) o hay algo que puedo mejorar?

+2

, probablemente podría simplificar esto solo para usar el objeto MetaData, y simplemente haga un simple "si os.path.exists (cachefile)" para determinar si está deshaciéndose o no. "Tabla ('usuarios', metadatos, autocarga = Verdadero)" y tal solo debe indicarse una vez ya que, como ya lo ha visto, omite el reflejo si la tabla ya está en el MetaData. – zzzeek

+1

Creo que no hay necesidad de cerrar un archivo cuando se usa dentro de una declaración 'with', pero eso no está relacionado. Su enfoque parece interesante, ¿está funcionando como se esperaba? – jadkik94

Cuestiones relacionadas