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 <[email protected]> wrote:
>
> On Tue, Mar 12, 2019 at 2:05 AM Tolstov Sergey <[email protected]> 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 [email protected].
> > To post to this group, send email to [email protected].
> > 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 [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.