Using Abstract Base Classes with ORM Table Classes

614 views
Skip to first unread message

Richard Damon

unread,
Mar 14, 2021, 8:53:13 PM3/14/21
to sqlal...@googlegroups.com
I have a lot of tables that have some similar functionality that I would
like to factor out into a base mix-in class that provides some common
methods. Some of these methods will want to use a method that must be
defined in the actual table ORM class, and would be an abstract method
in the base. If you just blindly do this you get the Python error of
multiple metaclasses, so I need to define a metaclass that inherets from
both ABCMeta and DeclarativeMeta, and then the Table ORM classes need to
mention declarative_base, the mixin and metaclass=mymeta. This works but
looks wordy.

If instead I try to put the mix-in between declarative_base and the
table class in the heirarchy, SQLAlchemy complains that it is missing
information for it to be a table (which is correct). If I put it as a
base to declarative_base the SQLAlchemy gets errors that it needs to
implement the abstract methods (and I of course can only do this once).

I could make the mixin not use the ABCMeta as its metaclass, but then if
I forget to define the abstract method in the table, I get no
complaints, at best I could catch the call to the abstract method
because it wasn't overridden.

Is this the way it is supposed to work, or am I missing some other trick?

Side question, when doing this sort of mix-in, does the order of the
mix-in and declarative_base matter, or is there a real preference?

--
Richard Damon

Mike Bayer

unread,
Mar 15, 2021, 8:17:15 AM3/15/21
to noreply-spamdigest via sqlalchemy
you no longer have to use DeclarativeMeta at all, you can use a class decorator:



if you are on 1.3, there's a way to get the same effect in 1.3 using the instrument_declarative function:  https://docs.sqlalchemy.org/en/13/orm/extensions/declarative/api.html?highlight=instrument_declarative#sqlalchemy.ext.declarative.instrument_declarative


which can be turned into an equivalent decorator.

that said I have not yet experimented with mapping classes that are also extending ABCMeta so I'm not sure if there are other issues.
-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper


To post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
You received this message because you are subscribed to the Google Groups "sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+...@googlegroups.com.


Richard Damon

unread,
Mar 16, 2021, 9:45:35 PM3/16/21
to sqlal...@googlegroups.com
First, just recently switched my developement form 1.3 to 1.4 based on
comments of time line, since I suspect I won't be done till next year,
will likely be releasing with 2.0. (I set the migration warnings
described in the porting guide).

Not sure I can use the class decorator, as I am using a recipie that
adds a declare_attr for __tablename__ to declarative_base to default to
the class name.

Looking on that page, it does look like from "Creating an Explicit Base
Non-Dynamically" that I could add a __abstract__ = True to the class to
get around the issue of declarative_base trying to make a real table out
of the intermediate class to provide the common code. (Looks like this
was in 1.3 too, but didn't see it).
>> http://www.sqlalchemy.org/ <http://www.sqlalchemy.org/>
>>
>> To post example code, please provide an MCVE: Minimal, Complete, and
>> Verifiable Example.  See  http://stackoverflow.com/help/mcve
>> <http://stackoverflow.com/help/mcve> for a full description.
>> --- 
>> You received this message because you are subscribed to the Google
>> Groups "sqlalchemy" group.
>> To unsubscribe from this group and stop receiving emails from it,
>> send an email to sqlalchemy+...@googlegroups.com
>> <mailto:sqlalchemy+...@googlegroups.com>.
>> <https://groups.google.com/d/msgid/sqlalchemy/e8d4c401-95fe-957f-7d65-3e37cd5150c6%40Damon-Family.org>.
>>
>
> --
> SQLAlchemy -
> The Python SQL Toolkit and Object Relational Mapper
>  
> http://www.sqlalchemy.org/ <http://www.sqlalchemy.org/>
>  
> To post example code, please provide an MCVE: Minimal, Complete, and
> Verifiable Example. See http://stackoverflow.com/help/mcve
> <http://stackoverflow.com/help/mcve> for a full description.
> ---
> You received this message because you are subscribed to the Google
> Groups "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to sqlalchemy+...@googlegroups.com
> <mailto:sqlalchemy+...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sqlalchemy/1f4f4ffc-d7dc-4ead-b031-a1e77c13586a%40www.fastmail.com
> <https://groups.google.com/d/msgid/sqlalchemy/1f4f4ffc-d7dc-4ead-b031-a1e77c13586a%40www.fastmail.com?utm_medium=email&utm_source=footer>.


--
Richard Damon

Reply all
Reply to author
Forward
0 new messages