SQLAlchemy:避免多重继承并拥有抽象基类 [英] Sqlalchemy: avoiding multiple inheritance and having abstract base class
问题描述
因此,我有一堆使用SQLAlchemy的表,它们被建模为对象,这些对象从结果继承到对declarative_base()
的调用.即:
So I have a bunch of tables using SQLAlchemy that are modelled as objects which inherit from the result to a call to declarative_base()
. Ie:
Base = declarative_base()
class Table1(Base):
# __tablename__ & such here
class Table2(Base):
# __tablename__ & such here
等等.然后,我想为每个数据库表类提供一些通用功能,根据文档执行此操作的最简单方法是进行多次继承:
Etc. I then wanted to have some common functionality available to each of my DB table classes, the easiest way to do this according to the docs is to just do multiple inheritance:
Base = declarative_base()
class CommonRoutines(object):
@classmethod
def somecommonaction(cls):
# body here
class Table1(CommonRoutines, Base):
# __tablename__ & such here
class Table2(CommonRoutines, Base):
# __tablename__ & such here
我对此不满意的是A)一般而言,多重继承有些棘手(解决诸如super()
调用之类的问题很棘手),B)如果我添加一个新表,我必须记住从Base
和CommonRoutines
继承,并且C)从某种意义上说,实际上是"CommonRoutines"类"is-a"类型的表.实际上,CommonBase
是一个抽象基类,它定义了一组字段&所有表都通用的例程.换种说法:它是一个"抽象表.
The thing I don't like about this is A) multiple inheritance in general is a bit icky (gets tricky resolving things like super()
calls, etc), B) if I add a new table I have to remember to inherit from both Base
and CommonRoutines
, and C) really that "CommonRoutines" class "is-a" type of table in a sense. Really what CommonBase
is is an abstract base class which defines a set of fields & routines which are common to all tables. Put another way: "its-a" abstract table.
所以,我想要的是这个
Base = declarative_base()
class AbstractTable(Base):
__metaclass__ = ABCMeta # make into abstract base class
# define common attributes for all tables here, like maybe:
id = Column(Integer, primary_key=True)
@classmethod
def somecommonaction(cls):
# body here
class Table1(AbstractTable):
# __tablename__ & Table1 specific fields here
class Table2(AbstractTable):
# __tablename__ & Table2 specific fields here
但是这当然是行不通的,因为我然后必须A)为AbstractTable
定义__tablename__
,B)事物的ABC方面引起各种麻烦,C)必须指出某种AbstractTable
与每个单独表之间的数据库关系的关系.
But this of course doesn't work, as I then have to A) define a __tablename__
for AbstractTable
, B) the ABC aspect of things causes all sorts of headaches, and C) have to indicate some sort of DB relationship between AbstractTable
and each individual table.
所以我的问题是:是否有可能以合理的方式实现这一目标?理想情况下,我想强制执行:
So my question: is it possible to achieve this in a reasonable way? Ideally I'd like to enforce:
- 没有多重继承
-
CommonBase
/AbstractTable
是抽象的(即无法实例化)
- No multiple inheritance
CommonBase
/AbstractTable
be abstract (ie cannot be instantiated)
推荐答案
这很简单,您只需使declarative_base()
返回使用cls=
参数从您CommonBase
继承的Base
类.还显示在扩展基础文档.然后,您的代码可能类似于以下内容:
It is pretty straigh-forward, you just make declarative_base()
to return a Base
class which inherits from your CommonBase
using cls=
parameter. Also shown in Augmenting The Base docs. Your code might then look similar to below:
class CommonBase(object):
@classmethod
def somecommonaction(cls):
# body here
Base = declarative_base(cls=CommonBase)
class Table1(Base):
# __tablename__ & Table1 specific fields here
class Table2(Base):
# __tablename__ & Table2 specific fields here
这篇关于SQLAlchemy:避免多重继承并拥有抽象基类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!