我正在使用SQLAlchemy,我的对象模型中的许多类具有相同的两个属性:id和(整数&主键)和name(字符串)。我试图避免在每个类中声明它们如此:
class C1(declarative_base()):
id = Column(Integer, primary_key = True)
name = Column(String)
#...
class C2(declarative_base()):
id = Column(Integer, primary_key = True)
name = Column(String)
#...
这样做的好方法是什么?我尝试过使用元类,但它还没有用。
答案 0 :(得分:10)
您可以将常用属性分解为mixin class,然后将其与declarative_base()
一起多次继承:
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
class IdNameMixin(object):
id = Column(Integer, primary_key=True)
name = Column(String)
class C1(declarative_base(), IdNameMixin):
__tablename__ = 'C1'
class C2(declarative_base(), IdNameMixin):
__tablename__ = 'C2'
print C1.__dict__['id'] is C2.__dict__['id']
print C1.__dict__['name'] is C2.__dict__['name']
编辑:您可能认为这会导致C1
和C2
共享相同的Column
个对象,但正如SQLAlchemy docs中所述,当源自mixin类时,列对象被复制。我已更新代码示例以演示此行为。
答案 1 :(得分:2)
你还可以使用Column的复制方法吗?这样,可以独立于表定义字段,而那些重用的字段只是field.copy() - ed。
id = Column(Integer, primary_key = True)
name = Column(String)
class C1(declarative_base()):
id = id.copy()
name = name.copy()
#...
class C2(declarative_base()):
id = id.copy()
name = name.copy()
#...
答案 2 :(得分:1)
我想我已经开始工作了。
我创建了一个派生自DeclarativeMeta的元类,并使其成为C1和C2的元类。在那个新的元类中,我只是说
def __new__(mcs, name, base, attr):
attr['__tablename__'] = name.lower()
attr['id'] = Column(Integer, primary_key = True)
attr['name'] = Column(String)
return super().__new__(mcs, name, base, attr)
似乎工作正常。