我正在使用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)
#...
有什么好办法呢?我尝试使用元类但它还没有用。
你可以把你的共同属性分解成一个 mixin类,并且多次继承它 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文档,列对象是 复制 当源自mixin类时。我已更新代码示例以演示此行为。
你可以把你的共同属性分解成一个 mixin类,并且多次继承它 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文档,列对象是 复制 当源自mixin类时。我已更新代码示例以演示此行为。
你还可以使用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()
#...
我想我得上班了。
我创建了一个派生自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)
它似乎工作正常。