그래, Using
또는 execution_context
데코레이터를 사용하는 좋은 예는 없으므로, 우선 두 가지를 함께 사용하지 마십시오. 아무것도 망가 뜨리지 않는 것처럼 보입니다. 그냥 중복되는 것처럼 보입니다. 논리적으로는 두 데코레이터가 블록의 지정된 모델 호출을 단일 연결/트랜잭션에서 실행하게하므로 의미가 있습니다.
두 가지의 유일한 차이점은 Using
을 사용하면 연결이 사용되는 특정 데이터베이스를 지정할 수 있다는 점입니다. 마스터/슬레이브에 유용합니다 (비록 Read slaves extension이 더 깨끗한 해결책 일지 모르지만).
두 개의 데이터베이스를 실행하고 ''의'두 번째 '데이터베이스에서 execution_context
을 사용하면 아무런 문제가 발생하지 않습니다. 연결이 블록 시작 부분에서 열리고 닫히고 끝나지만 모델에서 원래 데이터베이스를 계속 사용하기 때문에 쿼리가 실행되지 않습니다.
아래 코드 예이다. 모든 실행은 각 데이터베이스에 단 하나의 행만 추가되도록합니다.
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()))