SQLAlchemy:避免多重继承并拥有抽象基类 [英] Sqlalchemy: avoiding multiple inheritance and having abstract base class

查看:120
本文介绍了SQLAlchemy:避免多重继承并拥有抽象基类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我有一堆使用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)如果我添加一个新表,我必须记住从BaseCommonRoutines继承,并且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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆