繁体   English   中英

如何使用peewee的Use作为装饰器来动态指定数据库?

[英]how to use peewee's Using as a decorator to dynamically specify a database?

尽管peewee的文档中有许多食谱和例子; 我一直无法找到如何完成以下任务:

要获得更细粒度的控件,请查看Using context manager / decorator 这允许您在包装块的持续时间内指定要与给定模型列表一起使用的数据库。

我认为它会像...

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

但我没有找到例子,所以一个例子就是这个问题的答案。

是的,没有使用Usingexecution_context装饰器的好例子,所以首先要做的是:不要将两者结合使用。 它似乎没有破坏任何东西,似乎是多余的。 逻辑上这是有意义的,因为两个装饰器都会导致块中指定的模型调用在单个连接/事务中运行。

两者之间的唯一(/最大)不同的是, Using允许您指定的连接将使用特定数据库-主/从有用(虽然读奴隶扩展可能是一个清洁的解决方案)。

如果您使用两个数据库运行并尝试在“第二个”数据库上使用execution_context (在您的示例中为runtime_db ),则数据不会发生任何事情。 连接将在块的开头打开并关闭和结束,但不会对其执行任何查询,因为模型仍在使用其原始数据库。

下面的代码就是一个例子。 每次运行都应该导致每个数据库只添加一行。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM