2017-05-18 1 views
1

En dépit de nombreuses recettes et exemples dans la documentation de peewee; Je n'ai pas pu trouver comment effectuer ce qui suit:comment utiliser peewee Utilisation en tant que décorateur pour spécifier dynamiquement une base de données?

Pour un contrôle plus fin, consultez le gestionnaire de contexte à l'aide/décorateur. Cela vous permet de spécifier la base de données à utiliser avec une liste donnée de modèles pour la durée du bloc encapsulé.

Je suppose que ce serait quelque chose comme ...

db = MySQLDatabase(None) 


class BaseModelThing(Model): 
    class Meta: 
     database = db 


class SubModelThing(BaseModelThing): 
    '''imagine all the fields''' 
    class Meta: 
     db_table = 'table_name' 

runtime_db = MySQLDatabase('database_name.db', fields={'''imagine field mappings here''', **extra_stuff) 

@Using(runtime_db, [SubModelThing]) 
@runtime_db.execution_context() 
def some_kind_of_query(): 
    '''imagine the queries here''' 

mais je n'ai pas trouvé des exemples, donc un exemple serait la réponse à cette question.

Répondre

0

Oui, il n'y a pas un bon exemple d'utilisation Using ou les décorateurs execution_context, donc la première chose est: ne pas utiliser les deux ensemble. Il ne semble rien casser, semble juste redondant. Logiquement, cela est logique car les deux décorateurs font que les appels de modèle spécifiés dans le bloc s'exécutent dans une seule connexion/transaction. La seule différence (/ plus grande) entre les deux est que Using vous permet de spécifier la base de données particulière que la connexion utilisera - utile pour maître/esclave (bien que le Read slaves extension soit probablement une solution plus propre).

Si vous exécutez avec deux bases de données et que vous essayez d'utiliser execution_context sur la base de données 'deuxième' (dans votre exemple, runtime_db) rien ne se passera avec les données. Une connexion sera ouverte au début du bloc et fermée et à la fin, mais aucune requête ne sera exécutée car les modèles utilisent toujours leur base de données d'origine.

Le code ci-dessous est un exemple. Chaque exécution doit entraîner l'ajout d'une seule ligne à chaque base de données.

from peewee import * 

db = SqliteDatabase('other_db') 
db.connect() 

runtime_db = SqliteDatabase('cmp_v0.db') 
runtime_db.connect() 


class BaseModelThing(Model): 
    class Meta: 
     database = db 


class SubModelThing(Model): 
    first_name = CharField() 
    class Meta: 
     db_table = 'table_name' 

db.create_tables([SubModelThing], safe=True) 
SubModelThing.delete().where(True).execute() # Cleaning out previous runs 

with Using(runtime_db, [SubModelThing]): 
    runtime_db.create_tables([SubModelThing], safe=True) 
    SubModelThing.delete().where(True).execute() 

@Using(runtime_db, [SubModelThing], with_transaction=True) 
def execute_in_runtime(throw): 
    SubModelThing(first_name='asdfasdfasdf').save() 
    if throw: # to demo transaction handling in Using 
     raise Exception() 

# Create an instance in the 'normal' database 
SubModelThing.create(first_name='name') 

try: # Try to create but throw during the transaction 
    execute_in_runtime(throw=True) 
except: 
    pass # Failure is expected, no row should be added 

execute_in_runtime(throw=False) # Create a row in the runtime_db 

print 'db row count: {}'.format(len(SubModelThing.select())) 

with Using(runtime_db, [SubModelThing]): 
    print 'Runtime DB count: {}'.format(len(SubModelThing.select()))