2017-05-18 1 views
1

Trotz zahlreicher Rezepte und Beispiele in der Dokumentation von peewee; Ich war nicht in der Lage zu finden, wie die folgenden zu erreichen:Wie benutze ich peewee's Verwenden Sie als Dekorator um eine Datenbank dynamisch zu spezifizieren?

Für eine feinere Auswahl Besuche die Verwendung von Kontext-Manager/Dekorateur. Auf diese Weise können Sie die Datenbank angeben, die mit einer bestimmten Liste von Modellen für die Dauer des umschlossenen Blocks verwendet werden soll.

Ich nehme an, es so etwas wie gehen würde ...

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''' 

aber ich habe keine Beispiele gefunden, so ein Beispiel die Antwort auf diese Frage wäre.

Antwort

0

Ja, es gibt kein gutes Beispiel für die Verwendung Using oder die execution_context Dekorateure, so ist die erste Sache: Verwenden Sie nicht die beiden zusammen. Es scheint nichts zu zerbrechen, scheint nur überflüssig zu sein. Logisch ist das sinnvoll, da beide Decoratores bewirken, dass die angegebenen Modellaufrufe in dem Block in einer einzigen Verbindung/Transaktion ausgeführt werden.

Der einzige (/ größte) Unterschied zwischen den beiden ist, dass Using Sie die bestimmte Datenbank angeben können, die die Verbindung verwendet wird - nützlich für Master/Slave (obwohl die ist wahrscheinlich eine sauberere Lösung).

Wenn Sie mit zwei Datenbanken arbeiten und versuchen, execution_context auf der 'zweiten' Datenbank (in Ihrem Beispiel runtime_db) zu verwenden, wird nichts mit den Daten passieren. Eine Verbindung wird am Anfang des Blocks geöffnet und geschlossen und am Ende, aber es werden keine Abfragen ausgeführt, da die Modelle immer noch ihre ursprüngliche Datenbank verwenden.

Der folgende Code ist ein Beispiel. Bei jedem Lauf sollte nur eine Zeile zu jeder Datenbank hinzugefügt werden.

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())) 
Verwandte Themen