SQLAlchemy类装饰器用于__mapper_args__

0 投票
4 回答
3103 浏览
提问于 2025-04-17 17:15

我有很多类,它们和我的数据库结构有关系,属于多态的一部分。对于大多数这些类,我需要做:

__mapper_args__ = {'polymorphic_identity': unique_integer}
# unique_integer is a unique integer different for each class ex: 10

我想用一个装饰器来代替这个,也就是说:

@polid(10)
class ClassName(Inherited):
    # instead of repeating for each class the following:
    # __mapper_args__ = {'polymorphic_identity': 10}
    # I would like to have above decorator or something to do the trick.
    pass

我该怎么做呢?我需要用什么样的装饰器?下面这个不行(没有注册):

def polid(v):
    def x(f):
        f.__mapper_args__ = {'polymorphic_identity': v}
        return f
    return x

4 个回答

1

你的装饰器不管用,因为它试图在类已经创建后去修改这个类,而那个时候映射器已经设置好了。

def polid(value):
    return type("mixinclass", (object,), {"__mapper_args__": {'polymorphic_identity': value}})

class ClassName(polid(10), Inherited):
    pass

这段代码每次调用polid时都会创建一个全新的类,并且可以根据你的需要传入自定义的映射器参数。

2

使用一个 混合类。通常来说,混合类有点麻烦,但把一些共同的状态放进一个声明式类里,这样用似乎是个不错的主意。

class PolyMixin(object):
    __mapper_args__ = {'polymorphic_identity': 10}

class SomeTable(Base, PolyMixin):
    __tablename__ = "something"

class SomeOtherTable(Base, PolyMixin):
    __tablename__ = "something_else"
1

或许到目前为止,有一个稍微好一点、没那么神秘的解决方案可以使用:

def PID(value):
    ''' Mixin Class Generator For Polymorphic Identity Inheritance '''
    class MixinClassForPolymorphicIdentityInheritance: 
        __mapper_args__ = {'polymorphic_identity': value}
    return MixinClassForPolymorphicIdentityInheritance

用法:

class InheritingClass(PID(pidv), Parent): pass

(不幸的是)

撰写回答