我想在 SQLAlchemy 之上创建一个自定义接口,以便透明地支持一些预定义的混合属性。
具体来说,我想创建一个类SpecialColumn
和一个元类,以便当用户添加SpecialColumn
为类的属性时,我的自定义元类用两个 SQLAlchemy 替换该属性Column
并添加一个混合属性,该属性将这两个列获取和设置为一个元组。到目前为止,这是我的方法:
首先,我定义了我的特殊列类型:
class SpecialColumn(object):
pass
然后,我定义了一个继承自 DeclarativeMeta 的元类,它扫描类中的实例SpecialColumn
并用两个Column
s 和一个混合属性(定义为闭包)替换它们:
class MyDeclarativeMeta(DeclarativeMeta):
def __new__(cls, name, bases, attrs):
for name, col in attrs.items():
if isinstance(col, SpecialColumn):
# Replacing the column
del attrs[name]
col1_name = '_{0}_1'.format(name)
col2_name = '_{0}_2'.format(name)
attrs[col1_name] = Column(...)
attrs[col2_name] = Column(...)
# Adding the hybrid property
def getter(self):
return (getattr(self, col1_name), getattr(self, col2_name))
attrs[name] = hybrid_property(getter)
最后我declarative_base
用它构造了一个实例,并让用户用新的基础定义类:
MyBase = declarative_base(metaclass=MyDeclarativeMeta)
class MyClass(MyBase):
col1 = SpecialColumn()
col2 = Column(...)
现在我的问题是:首先,我的方法正确吗?其次,如何使用元类添加setter?这样做是否正确:
def setter(self, (v1, v2)):
setattr(self, col1_name, v1)
setattr(self, col2_name, v2)
然后干脆attrs[name].setter(setter)
呢?