Issue: Mapping class inheritance hierarchies
Author: apotapov
State: closed
Created: 2017-10-05 17:21:32

Pardon my ignorance, as I'm coming to python web frameworks from Rails-land. 

I'm wondering if peewee offers Single Table Inheritance similar to Rails. There seems to be an option for it in SQLAlchemy: http://docs.sqlalchemy.org/en/latest/orm/inheritance.html#single-table-inheritance

If not, what are my options?

I'm not familiar with the SQLAlchemy implementation or behavior, but with Peewee inheriting a class creates a completely separate table with all the columns from the parent plus whatever is defined on the child class. There are no magic foreign-keys or anything like that.

Thanks for a quick response.

Single Table Inheritance (STI) is a fairly common pattern: https://en.wikipedia.org/wiki/Single_Table_Inheritance It make querying much simpler at the base class level, meanwhile abstracting implementation to child classes. It's also standard in Rails.

I was planning to use peewee for an app that I'm migrating from Rails to Flask, but not having STI is a non-starter for me. Would love to see it as a feature added in the future. For now, SQLAlchemy will have to make do.

👍 

Business model is not like database table, it encapsulates **behavior** besides data.

There is a common case that different models have similar data structure but behavior differently. With OOD, these models could be designed as subclasses inherited from one base class and overwriting some methods to get different behaviors.

No disagreement here. You can subclass models in Peewee as long as you understand that the subclass will be its own table with no back-reference/pointer to the parent class table.

I was simply pointing out that STI is a valid usecase for an ORM. And this feature seems to be missing from peewee. If that's by design, then that's fine. However, STI support would be much appreciated, especially to those of us coming from Rails world. And isn't that a win for the python ecosystem? ;)

Don't you mean multi-table-inheritance (MTI)? Or maybe we're talking about the same thing...presenting a model class that composes (behind-the-scenes) the contents of two separate tables, related by a 1-to-1 from parent->child?

The problem with doing this kind of magic is that it touches nearly every complex part of peewee. Figuring out how to join two models now has a special-case. Figuring out how to map column data from a flat row returned by the cursor into a model graph also has a special-case. Selecting columns has a special case (do we need the join or can we get away without it, depending on the columns the user requests?). Etc.

I think we are much more like talking about Single Table Inheritance(STI): different models share one single table, distinguished with value of a specific column, as [the SQLAlchemy example](http://docs.sqlalchemy.org/en/latest/orm/inheritance.html#single-table-inheritance).

Ohhh, thanks @psjay I understand now. I glanced at the example without reading all the details. So SQLAlchemy maps all inherited columns onto a single table and then differentiates based on some type column. That's less smelly to me than multi-table-inheritance, but still is a level of magix that I don't want to maintain or have to debug :)