如何使用PonyORM动态创建实体?

问题描述 投票:0回答:1

我想通过工厂方法在Pony ORM中创建数据库实体,以避免类似表的代码重复。

这是我没有完全工作的最小例子:

from pony.orm import *


def factory(db, tablename):
    class TableTemplate(db.Entity):
        _table_ = tablename
        first_name = Required(str)
        last_name = Required(str)
        composite_index(first_name, last_name)
    return TableTemplate


db = Database(provider='sqlite', filename=':memory:')
Table1 = factory(db, "TABLE_1")

# the following line produces the exception:
#    pony.orm.core.ERDiagramError: Entity TableTemplate already exists
Table2 = factory(db, "TABLE_2")

db.generate_mapping(create_tables=True)
with db_session:
    Table1(first_name="foo", last_name="bar")

使用type创建具有动态名称的类可以避免异常,但这对composite_index不起作用...

有没有一个很好的方法与Pony ORM有一个桌子工厂?

python factory-pattern ponyorm
1个回答
2
投票

这是我对你的班级工厂的看法:

def factory(db, tablename):
    fields = {
        '_table': tablename,
        'first_name': Required(str)
        # rest of the fields
    }
    table_template = type(tablename.capitalize(),(db.Entity,),fields)
    return table_template

这将通过在tablename中大写名称并设置描述符来创建一个类。虽然我不确定元类

关于composite_index问题的最新消息

composite_index通过调用此方法使用一些非常模糊的功能:

def _define_index(func_name, attrs, is_unique=False):
    if len(attrs) < 2: throw(TypeError,
        '%s() must receive at least two attributes as arguments' % func_name)
    cls_dict = sys._getframe(2).f_locals
    indexes = cls_dict.setdefault('_indexes_', [])
    indexes.append(Index(*attrs, is_pk=False, is_unique=is_unique))

一些实验告诉我你可以通过自己添加字段来执行相同的操作。所以这将使我们的工厂qazxsw poi变量看起来像这样:

fields

试一试,让我知道。

实验更新

最终的代码是这样的:

fields = {
        '_table': tablename,
        'first_name': Required(str),
        '_indexes_':[Index(('first_name','last_name'),is_pk=False,is_unique=False)]
        # rest of the fields
    }
© www.soinside.com 2019 - 2024. All rights reserved.