2

Been searching for this answer for a bit now, but I can't seem to find it, as everything refers back to joined table inheritance, which I understand, but do not want to use. I am looking to create multiple classes in SQLAlchemy that are identical in table construction, only differing in the class name and database table name. I am intentionally separating the tables and not using a discriminator because I expect these tables to grow to very large sizes. There is also a potential that the table schemas may diverge slowly over time, with some fields added to one but not another.

I know the following code doesn't work, as SQLAlchemy tries to find a foreign key for joined table inheritance rather than making them independent tables, but it's basically what I'm going for. I've been over the docs, but can't figure out the way to properly implement this. Is there a way (or multiple ways) to do this?

from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class HDD(Base):
    """Class representing a hard drive."""

    __tablename__ = 'HDDs'

    _id = Column(
        Integer,
        doc="Auto-incrementing primary key",
        name="id",
        primary_key=True)
    manufacturer = Column(
        String(40),
        doc="Hard drive manufacturer.")
    ...

class SDD(HDD):
    __tablename__ = 'SSDs'
    ...
0

3 Answers 3

5

Use __abstract__ = True with no __tablename__ on the base class, and inherit from that.

class HDD(Base):
    __abstract__ = True
    _id = ...

class SDD(HDD):
    __tablename__ = 'SSDs'

class SSD2(HDD):
    __tablename = 'SSDs2'
Sign up to request clarification or add additional context in comments.

2 Comments

I haven't tried this method yet (see below for my solution), but I may give it a shot in the future!
Got around trying this too, and I like it a lot! Very clean!
0

This looks like Concrete Table Inheritance, as discussed in the Mapping Class Inheritance Hierarchies chapter of SQLAlchemy docs.

1 Comment

Thanks for your help, including via IRC. I mentioned you above in thanks. :)
0

This is the way I ended up getting this working, with help from inklesspen from #sqlalchemy on freenode. (Thank you!)

class ComponentMixin(object):
    """Pythonic Mixin that defines columns common to most component types."""

    _id = Column(
        Integer,
        doc="Auto-incrementing primary key",
        name="id",
        primary_key=True)
    ....

    @declared_attr
    def _server_id(self):  # pylint: disable=R0201
        """
        Foreign key to owning server.

        MUST BE A DECLARED_ATTR since it's a foreign key!
        """

Subclass below inherits:

class HDD(ComponentMixin, ConcreteBase, Base):
    """Class representing a hard drive."""

    __tablename__ = 'HDDs'

    __mapper_args__ = {
        'polymorphic_identity': 'hdd',
        'concrete': True}

2 Comments

and was SDD still a subclass of HDD, or was it a subclass of the mixin... i.e. class SDD(HDD): or class SDD(ComponentMixin, ConcreteBase, Base): ??
A more complete implementation would be helpful. E.g. how is _server_id(self): implemented? Does it return a Column object? e.g. Column( Integer, ForeignKey( 'server.id' ) ) or something similar?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.