Here's the POC:

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.declarative import declared_attr

Base = declarative_base()


class A(Base):
    __tablename__ = 'a'

    id = Column(Integer, primary_key=True)
    data = Column(String)
    type = Column(String)

    __mapper_args__ = {
        "polymorphic_on": type,
        "polymorphic_identity": "a"
    }

class MyRegistry(dict):
    def _create_class(self, key):
        if key == "b":

            class B(A):
                __mapper_args__ = {
                    "polymorphic_identity": "b"
                }

            return B.__mapper__
        else:
            raise KeyError(key)

    def __missing__(self, key):
        self[key] = val = self._create_class(key)
        return val

A.__mapper__.polymorphic_map = MyRegistry(**A.__mapper__.polymorphic_map)

e = create_engine("sqlite://", echo=True)
with e.connect() as conn:
    conn.execute(
        "CREATE TABLE a (id INTEGER PRIMARY KEY, data VARCHAR, "
        "type VARCHAR)")
    conn.execute(
        "INSERT INTO a (id, data, type) "
        "VALUES (1, 'some object', 'b')")

s = Session(e)

print(s.query(A).all())



On Tue, Mar 12, 2019 at 9:38 AM Mike Bayer <mike...@zzzcomputing.com> wrote:
>
> On Tue, Mar 12, 2019 at 2:05 AM Tolstov Sergey <whistler...@gmail.com> wrote:
> >
> > Addition.
> >  If i create all possible classes i may get a low perfomance (rel to root 
> > class)
>
> I understand the startup time issue, although again if your
> application runs long enough, all that time will ultimately have been
> taken.    Once you do have all the classes loaded, I'm not sure how
> that affects performance going forward unless your server is running
> out of memory as a result.   There should be no impact on performance
> if your application has 3 or 300 classes and mappers loaded in memory
> provided you have enough memory and provided these classes aren't
> spinning off some kind of background work by existing.
>
> Anyway, this is risky, because if you have a multithreaded /
> multi-green-thread application running lots of queries, and all of
> them are digging into your registry, creating classes and new mapper()
> objects on the fly, how are you guarding against two queries trying to
> access the same mapper() at the same time and both trying to create
> it?  Are you mutexing around the whole get() operation or otherwise
> gating the production of the new class + mapper() (hurts performance
> also)?   Additionally, a mapper needs to have the configure step
> called, which uses a mutex so should be threadsafe.
>
> Beyond that, this doesn't work from a mapping perspective, because the
> root mapper needs to know about the attributes on the subclass in
> order to load correctly.  I can give you a POC that works only if you
> use single table inheritance and the subclasses have no columns on
> them, which is quite limited, see below.  Otherwise, the loading
> system does not have the information it needs if new classes are added
> on the fly in the middle of the loading process.
>
> Bigger issue is that if you've built a datamodel that takes too long
> to start up because it has many hundreds of classes that usually arent
> needed, this may be a sign of a bigger architectural problem.     If
> OTOH these polymorphic classes are generated anonymously, e.g. they
> really aren't business objects but just data containers, then that's
> not really how the polymorphic inheritance feature was meant to be
> used.
>
> >
> > --
> > SQLAlchemy -
> > The Python SQL Toolkit and Object Relational Mapper
> >
> > http://www.sqlalchemy.org/
> >
> > 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+unsubscr...@googlegroups.com.
> > To post to this group, send email to sqlalchemy@googlegroups.com.
> > Visit this group at https://groups.google.com/group/sqlalchemy.
> > For more options, visit https://groups.google.com/d/optout.

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

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+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to