the usage of "classproperty" here suggests you're using SQLAlchemy's
internal function, which has special meaning in that it gets treated
like declared_attr, and you can see in INSERT it is using HybridModel
for everyone. Using a different classproperty approach below the test
case passes.
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base, declared_attr
from sqlalchemy.ext.hybrid import hybrid_property, Comparator
Base = declarative_base()
class classproperty(property):
"""A decorator that behaves like @property except that operates
on classes rather than instances.
The decorator is currently special when using the declarative
module, but note that the
:class:`~.sqlalchemy.ext.declarative.declared_attr`
decorator should be used for this purpose with declarative.
"""
def __init__(self, fget, *arg, **kw):
super(classproperty, self).__init__(fget, *arg, **kw)
self.__doc__ = fget.__doc__
def __get__(desc, self, cls):
return desc.fget(cls)
class ModelBase(Base):
__abstract__ = True
def __repr__(self):
return "{} ({}:{})".format(type(self).__name__, self.name, self.id)
class HybridType(ModelBase):
__tablename__ = 'hybrid_types'
id = Column(Integer, primary_key=True)
name = Column(Text)
class HybridModel(ModelBase):
__tablename__ = 'hybrids'
id = Column(Integer, primary_key=True)
name = Column(Text)
hybrid_type_id = Column(Integer, ForeignKey('hybrid_types.id'),
nullable=False)
hybrid_type = relationship('HybridType')
def __init__(self, *args, **kwargs):
self.hybrid_type_name = self.hybrid_type_identity
return super().__init__(*args, **kwargs)
@classproperty
def hybrid_type_identity(cls):
return cls.__name__
@declared_attr
def __mapper_args__(cls):
return dict(
polymorphic_on=cls.hybrid_type_name_subquery(),
polymorphic_identity=cls.hybrid_type_identity,
)
@hybrid_property
def hybrid_type_name(self):
return self.hybrid_type.name
@hybrid_type_name.setter
def hybrid_type_name(self, value):
self.hybrid_type_id = (
select([HybridType.id]).
where(HybridType.name == value)
)
@hybrid_type_name.expression
def hybrid_type_name(cls):
return cls.hybrid_type_name_subquery()
@classmethod
def hybrid_type_name_subquery(cls):
return select([HybridType.name]).where(HybridType.id ==
cls.hybrid_type_id).as_scalar()
class HybridComparator(Comparator):
def operate(self, op, other):
return op(HybridType.hybrid_type_id,
select([HybridType.id]).where(HybridType.name == other).as_scalar())
@hybrid_type_name.comparator
def hybrid_type_name(cls):
return cls.HybridComparator(cls)
class HybridAlpha(HybridModel):
pass
class Hybrita(HybridModel):
pass
e = create_engine("sqlite://", echo=True)
Base.metadata.create_all(e)
session = Session(e)
session.add(HybridType(name=HybridAlpha.hybrid_type_identity))
session.add(HybridType(name=Hybrita.hybrid_type_identity))
session.add(HybridAlpha(name='alpha_instance'))
session.add(Hybrita(name='beta_instance'))
all_alphas = session.query(HybridAlpha).all()
assert session.query(HybridModel).count() == 2
print("------")
assert session.query(HybridAlpha).count() == 1
assert session.query(Hybrita).count() == 1
On 12/29/2016 11:09 AM, Tucker Beck wrote:
Mike,
Here's the solution I came up with. It shows the 'inverted select' used
in the comparator vs the hybrid expression
class ModelBase(db.Model):
__abstract__ = True
def __repr__(self):
return "{} ({}:{})".format(type(self).__name__, self.name
<http://self.name>, self.id <http://self.id>)
class HybridType(ModelBase):
__tablename__ = 'hybrid_types'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Text)
class HybridModel(ModelBase):
__tablename__ = 'hybrids'
id = db.Column(db.BigInteger, primary_key=True)
name = db.Column(db.Text)
hybrid_type_id = db.Column(db.Integer,
db.ForeignKey('hybrid_types.id <http://hybrid_types.id>'), nullable=False)
hybrid_type = db.relationship('HybridType')
def __init__(self, *args, **kwargs):
self.hybrid_type_name = self.hybrid_type_identity
return super().__init__(*args, **kwargs)
@classproperty
def hybrid_type_identity(cls):
return inflection.underscore(cls.__name__)
@declared_attr
def __mapper_args__(cls):
return dict(
polymorphic_on=cls.hybrid_type_name_subquery(),
polymorphic_identity=cls.hybrid_type_identity,
)
@hybrid_property
def hybrid_type_name(self):
return self.hybrid_type.name <http://self.hybrid_type.name>
@hybrid_type_name.setter
def hybrid_type_name(self, value):
self.hybrid_type_id = (
select([HybridType.id]).
where(HybridType.name == value)
)
@hybrid_type_name.expression
def hybrid_type_name(cls):
return cls.hybrid_type_name_subquery()
@classmethod
def hybrid_type_name_subquery(cls):
return select([HybridType.name]).where(HybridType.id ==
cls.hybrid_type_id).as_scalar()
class HybridComparator(Comparator):
def operate(self, op, other):
return op(HybridType.hybrid_type_id,
select([HybridType.id]).where(HybridType.name == other).as_scalar())
@hybrid_type_name.comparator
def hybrid_type_name(cls):
return cls.HybridComparator(cls)
class HybridAlpha(HybridModel):
pass
class HybridBeta(HybridModel):
pass
class TestHybrids:
def test_all_query(self):
db.session.add(HybridType(name=HybridAlpha.hybrid_type_identity))
db.session.add(HybridType(name=HybridBeta.hybrid_type_identity))
db.session.add(HybridAlpha(name='alpha_instance'))
db.session.add(HybridBeta(name='beta_instance'))
all_alphas = HybridAlpha.query.all()
assert HybridModel.query.count() == 2
assert HybridAlpha.query.count() == 1
assert HybridBeta.query.count() == 1
On Wed, Dec 28, 2016 at 2:19 PM, mike bayer <mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>> wrote:
On 12/27/2016 04:36 PM, Tucker Beck wrote:
Mike (or whoever else might have insight):
I used the pattern above, and it worked great until I tried use
it for a
really large table that I was querying and filtering by the hybrid
property. Something like this:
query(HybridModel).filter_by(hybrid_type_name='alpha')
Well I mentioned a correlated subquery won't scale here.
The resulting query does a seq-scan applying a sub-select to get the
hybrid_type_name and then comparing it to the filter value
('alpha' in
the example). Obviously, this is sub-optimal, and I want the
query to do
an index-scan comparing the hybrid_type_id matching the
filter_value to
the hybrid_type_id of each row. The table has an index on
hybrid_type_id, so that query is orders of magnitude faster. Before
using this revised pattern we discussed, I got the query I wanted by
adding a comparator to my class that basically inverts the
select used
by the hybrid property expression. That worked great before
using this
pattern.
I'm not sure what "invert the select" looks like.
However, with the new pattern, the delcared_attr __mapper_args__
attempts to use the expression from the comaprator for
polymorphic_on,
and that query results in an integer (primary key) which won't work
because we defined our polymorphic identities using the name
I'm not understanding this part either, can this be demonstrated
with the simple test script I gave you ?
Do you have any ideas on how I might resolve this issue?
On Sat, Dec 3, 2016 at 4:25 PM, mike bayer
<mike...@zzzcomputing.com <mailto:mike...@zzzcomputing.com>
<mailto:mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>>> wrote:
On 12/01/2016 05:29 PM, Tucker Beck wrote:
This is what I ended up with, and it *seems* to work pretty
well. Does
my approach here pass the sniff test?
everything looks idiomatic, so if it does what you need,
then it's
greatg!
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.ext.declarative import declarative_base,
declared_attr
from sqlalchemy.orm import sessionmaker, relationship,
column_property
from sqlalchemy import (
Column, Integer, ForeignKey, Text,
select, create_engine,
)
Base = declarative_base()
class HybridType(Base):
__tablename__ = 'hybrid_types'
id = Column(Integer, primary_key=True)
name = Column(Text)
class HybridModel(Base):
__tablename__ = 'hybrids'
hybrid_type_identity = 'base'
id = Column(Integer, primary_key=True)
name = Column(Text)
hybrid_type_id = Column(Integer,
ForeignKey('hybrid_types.id <http://hybrid_types.id>
<http://hybrid_types.id>
<http://hybrid_types.id>'))
hybrid_type = relationship('HybridType')
@declared_attr
def __mapper_args__(cls):
return dict(
polymorphic_on=cls.hybrid_type_name,
polymorphic_identity=cls.hybrid_type_identity,
)
def __repr__(self):
return "{} ({}:{})".format(type(self).__name__,
self.name <http://self.name> <http://self.name>
<http://self.name>, self.id <http://self.id>
<http://self.id> <http://self.id>)
def __init__(self, **kwargs):
self.hybrid_type_name = self.hybrid_type_identity
super(HybridModel, self).__init__(**kwargs)
@hybrid_property
def hybrid_type_name(self):
return self.hybrid_type.name
<http://self.hybrid_type.name>
<http://self.hybrid_type.name>
<http://self.hybrid_type.name>
@hybrid_type_name.expression
def hybrid_type_name(cls):
return (
select([HybridType.name]).
where(HybridType.id == cls.hybrid_type_id).
as_scalar()
)
@hybrid_type_name.setter
def hybrid_type_name(self, value):
self.hybrid_type_id = (
select([HybridType.id]).
where(HybridType.name == value)
)
class HybridAlpha(HybridModel):
hybrid_type_identity = 'alpha'
class HybridBeta(HybridModel):
hybrid_type_identity = 'beta'
engine = create_engine('sqlite:///:memory:', echo=False)
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
session.add(HybridType(name='base'))
session.add(HybridType(name='alpha'))
session.add(HybridType(name='beta'))
session.add(HybridModel(name='base_instance'))
session.add(HybridAlpha(name='alpha_instance'))
session.add(HybridBeta(name='beta_instance'))
print(session.query(HybridModel).all())
print(session.query(HybridAlpha).all())
print(session.query(HybridAlpha).one().hybrid_type_name)
session.query(HybridAlpha).one().hybrid_type_name = 'beta'
print(session.query(HybridBeta).all())
On Wed, Nov 30, 2016 at 7:20 AM, mike bayer
<mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>
<mailto:mike...@zzzcomputing.com <mailto:mike...@zzzcomputing.com>>
<mailto:mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>
<mailto:mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>>>> wrote:
On 11/29/2016 07:31 PM, Tucker Beck wrote:
Thanks for this! What allows the query to filter
in the
derived
classes
when using a column property instead of a hybrid
property? Is it
declaring the __mapper_args__ in the base class
declaration
instead of
after it?
Yea I don't think setting __mapper_args__ after the
fact on the
class does anything. Those __mapper_args__ are
only for the
mapper() constructor directly, which gets called
when the
class is
declared.
you can set the actual polymorphic_on property right now
only using
the special
class.__mapper__._set_polymorphic_on(<something>),
that's one of a very few setters that's available on
the mapper
after the fact and even then it's not fully public
API right
now.
Also, it seems like having the hybrid_type_prop
column
property
obviates
the need for the hybrid property
hybrid_type_name...that is,
except for
the setter. Is there a way to give a
column_property a
setter?
a column_property against a SQL expression is strictly a
read-only
thing, since "writing" to it makes no sense in terms of
persistence.
the column_property aspect here isn't strictly
necessary,
the mapper
will create the property internally as a special
case for the
polymorphic_on setting if not provided. the example
can be
re-organized w/ your hybrid in at least two ways:
class HybridModel(Base):
# ...
@declared_attr
def __mapper_args__(cls):
return {
"polymorphic_on": cls.hybrid_type_name
}
or
class HybridModel(Base):
# ...
_hybrid_name_expr = (
select([HybridType.name]).
where(HybridType.id == hybrid_type_id).
as_scalar()
)
__mapper_args__ = {
"polymorphic_on": _hybrid_name_expr
}
# ...
@hybrid_type_name.expression
def hybrid_type_name(cls):
return cls._hybrid_name_expr
On Tue, Nov 29, 2016 at 2:59 PM, mike bayer
<mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>
<mailto:mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>>
<mailto:mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>
<mailto:mike...@zzzcomputing.com <mailto:mike...@zzzcomputing.com>>>
<mailto:mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>
<mailto:mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>>
<mailto:mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>
<mailto:mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>>>>> wrote:
On 11/29/2016 05:01 PM, Tucker Beck wrote:
The issue with using the foreign_key integer
value as the
discriminator
is that you won't know what that is at class
declaration
time. The
type_name, however, you can declare as a
part of the
class as
you would
with a normal string discriminator. I'm
not sure
how you
would do a
correlated subquery for the polymorphic_on
attribute. I
modified the
query object so that I could filter
results for
the derived
classes. It
doesn't seem like that happens
automatically.
Maybe I'm
just not
doing
it right.
The correlated subquery will not scale as
well as a
direct
identifier, but here is an adaption of your
test using
column_property(), and you should be able to set
polymorphic_on to
the select() object directly too. There's
another
example
of this
at
http://docs.sqlalchemy.org/en/latest/orm/mapping_api.html?highlight=polymorphic_on#sqlalchemy.orm.mapper.params.polymorphic_on
<http://docs.sqlalchemy.org/en/latest/orm/mapping_api.html?highlight=polymorphic_on#sqlalchemy.orm.mapper.params.polymorphic_on>
<http://docs.sqlalchemy.org/en/latest/orm/mapping_api.html?highlight=polymorphic_on#sqlalchemy.orm.mapper.params.polymorphic_on
<http://docs.sqlalchemy.org/en/latest/orm/mapping_api.html?highlight=polymorphic_on#sqlalchemy.orm.mapper.params.polymorphic_on>>
<http://docs.sqlalchemy.org/en/latest/orm/mapping_api.html?highlight=polymorphic_on#sqlalchemy.orm.mapper.params.polymorphic_on
<http://docs.sqlalchemy.org/en/latest/orm/mapping_api.html?highlight=polymorphic_on#sqlalchemy.orm.mapper.params.polymorphic_on>
<http://docs.sqlalchemy.org/en/latest/orm/mapping_api.html?highlight=polymorphic_on#sqlalchemy.orm.mapper.params.polymorphic_on
<http://docs.sqlalchemy.org/en/latest/orm/mapping_api.html?highlight=polymorphic_on#sqlalchemy.orm.mapper.params.polymorphic_on>>>
<http://docs.sqlalchemy.org/en/latest/orm/mapping_api.html?highlight=polymorphic_on#sqlalchemy.orm.mapper.params.polymorphic_on
<http://docs.sqlalchemy.org/en/latest/orm/mapping_api.html?highlight=polymorphic_on#sqlalchemy.orm.mapper.params.polymorphic_on>
<http://docs.sqlalchemy.org/en/latest/orm/mapping_api.html?highlight=polymorphic_on#sqlalchemy.orm.mapper.params.polymorphic_on
<http://docs.sqlalchemy.org/en/latest/orm/mapping_api.html?highlight=polymorphic_on#sqlalchemy.orm.mapper.params.polymorphic_on>>
<http://docs.sqlalchemy.org/en/latest/orm/mapping_api.html?highlight=polymorphic_on#sqlalchemy.orm.mapper.params.polymorphic_on
<http://docs.sqlalchemy.org/en/latest/orm/mapping_api.html?highlight=polymorphic_on#sqlalchemy.orm.mapper.params.polymorphic_on>
<http://docs.sqlalchemy.org/en/latest/orm/mapping_api.html?highlight=polymorphic_on#sqlalchemy.orm.mapper.params.polymorphic_on
<http://docs.sqlalchemy.org/en/latest/orm/mapping_api.html?highlight=polymorphic_on#sqlalchemy.orm.mapper.params.polymorphic_on>>>>.
For the "use the id" approach, you would need to
query from
HybridType up front and populate the
polymorphic_identity
attributes
after the fact, this is a feature that is
not directly
supported yet
but there is a recipe to do so at
https://bitbucket.org/zzzeek/sqlalchemy/issues/2792/settable-polymorphic-identity
<https://bitbucket.org/zzzeek/sqlalchemy/issues/2792/settable-polymorphic-identity>
<https://bitbucket.org/zzzeek/sqlalchemy/issues/2792/settable-polymorphic-identity
<https://bitbucket.org/zzzeek/sqlalchemy/issues/2792/settable-polymorphic-identity>>
<https://bitbucket.org/zzzeek/sqlalchemy/issues/2792/settable-polymorphic-identity
<https://bitbucket.org/zzzeek/sqlalchemy/issues/2792/settable-polymorphic-identity>
<https://bitbucket.org/zzzeek/sqlalchemy/issues/2792/settable-polymorphic-identity
<https://bitbucket.org/zzzeek/sqlalchemy/issues/2792/settable-polymorphic-identity>>>
<https://bitbucket.org/zzzeek/sqlalchemy/issues/2792/settable-polymorphic-identity
<https://bitbucket.org/zzzeek/sqlalchemy/issues/2792/settable-polymorphic-identity>
<https://bitbucket.org/zzzeek/sqlalchemy/issues/2792/settable-polymorphic-identity
<https://bitbucket.org/zzzeek/sqlalchemy/issues/2792/settable-polymorphic-identity>>
<https://bitbucket.org/zzzeek/sqlalchemy/issues/2792/settable-polymorphic-identity
<https://bitbucket.org/zzzeek/sqlalchemy/issues/2792/settable-polymorphic-identity>
<https://bitbucket.org/zzzeek/sqlalchemy/issues/2792/settable-polymorphic-identity
<https://bitbucket.org/zzzeek/sqlalchemy/issues/2792/settable-polymorphic-identity>>>>.
from sqlalchemy.ext.hybrid import
hybrid_property
from sqlalchemy.ext.declarative import
declarative_base
from sqlalchemy.orm import sessionmaker,
relationship,
column_property
from sqlalchemy import (
Column, Integer, ForeignKey, Text,
select, create_engine,
)
Base = declarative_base()
class HybridType(Base):
__tablename__ = 'hybrid_types'
id = Column(Integer, primary_key=True)
name = Column(Text)
class HybridModel(Base):
__tablename__ = 'hybrids'
id = Column(Integer, primary_key=True)
name = Column(Text)
hybrid_type_id = Column(Integer,
ForeignKey('hybrid_types.id
<http://hybrid_types.id> <http://hybrid_types.id>
<http://hybrid_types.id>
<http://hybrid_types.id>'))
hybrid_type = relationship('HybridType')
hybrid_type_prop = column_property(
select([HybridType.name]).
where(HybridType.id == hybrid_type_id).
as_scalar()
)
__mapper_args__ = {
"polymorphic_on": hybrid_type_prop
}
def __repr__(self):
return "{}
({}:{})".format(type(self).__name__,
self.name <http://self.name> <http://self.name>
<http://self.name>
<http://self.name>, self.id <http://self.id>
<http://self.id>
<http://self.id> <http://self.id>)
def __init__(self, **kwargs):
self.hybrid_type_name =
type(self).__mapper_args__['polymorphic_identity']
super(HybridModel,
self).__init__(**kwargs)
@hybrid_property
def hybrid_type_name(self):
return self.hybrid_type.name
<http://self.hybrid_type.name>
<http://self.hybrid_type.name>
<http://self.hybrid_type.name>
<http://self.hybrid_type.name>
@hybrid_type_name.setter
def hybrid_type_name(self, value):
self.hybrid_type_id = (
select([HybridType.id]).
where(HybridType.name == value)
)
class HybridAlpha(HybridModel):
__mapper_args__ =
{'polymorphic_identity': 'alpha'}
class HybridBeta(HybridModel):
__mapper_args__ =
{'polymorphic_identity': 'beta'}
engine = create_engine('sqlite:///:memory:',
echo=True)
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
session.add(HybridType(name='alpha'))
session.add(HybridType(name='beta'))
session.add(HybridAlpha(name='alpha_instance'))
session.add(HybridBeta(name='beta_instance'))
print(session.query(HybridAlpha).all())
On Tue, Nov 29, 2016 at 7:16 AM, mike bayer
<mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>
<mailto:mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>>
<mailto:mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>
<mailto:mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>>>
<mailto:mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>
<mailto:mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>>
<mailto:mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>
<mailto:mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>>>>
<mailto:mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>
<mailto:mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>>
<mailto:mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>
<mailto:mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>>>
<mailto:mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>
<mailto:mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>>
<mailto:mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>
<mailto:mike...@zzzcomputing.com
<mailto:mike...@zzzcomputing.com>>>>>> wrote:
On 11/28/2016 05:58 PM, Tucker Beck
wrote:
Hello, I'm writing today about an
interesting
problem we ran
into with
our sqlalchemy based data store api.
Our schema is based on the
star-schema idea
where we have a
large 'fact
table' with lots of rows. Within
that table,
each row has a
foreign key
to a small 'dimension table' in
which
each row
has a unique
name. Thus,
the type of each row can be
defined by the
relationship
between
the fact
row and the dimension row.
We wanted to be able to use
SQLAlchemy
to add
some custom
functionality
for the different types of rows
we have
in our 'fact
table'. After
learning about SQLAlchemy's
inheritance
models, I
decided to see
if we
could support the schema that we
had already
devised for our
project.
The single-inheritance pattern
seemed to
fit the
best, but I
couldn't
find a single case where someone
was using a
star-schema and
needed the
type discriminator to be derived
from the
foreign key to the
dimension
table.
Further, I found as I was
digging into the
mechanics of the
thing that
you could not create a row in
the fact table
that was
typed by the
derived class at creation time.
And, you
cannot
limit
queries
from the
fact table by creating the queries
against the
derived
classes.
Suppose
that (using declarative base) I
have the
fact table
represented by a
model called HybridModel. This
model has two
derived classes
HybridAlpha
and HybridBeta. I would like to
be able to
create a new
row in
the table
wrapped by HybridModel by calling
something like
HybridAlpha(**kwargs)
and have the type of the new row
reflect the
inheritance
model I've
described above. Next I wanted
to be able to
formulate a
query
against
one of the derived models and
have it
limited by the
type associated
with the derived class. So, calling
something like
`session.query(HybridAlpha).all()` would
only return
rows with a
type
associated with the HybridAlpha
model.
After a lot of tinkering and
experimentation,
I've come
up with the
following solution:
https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89>
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89>>
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89>
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89>>>
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89>
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89>>
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89>
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89>>>>
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89>
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89>>
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89>
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89>>>
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89>
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89>>
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89>
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89
<https://gist.github.com/dusktreader/2658dedb8ca8e2fd941f8075c75b3c89>>>>>
I would appreciate any thoughts and
feedback on the
matter. I'm
not sure
that my approach to this
solution has been
sound, and I
would
appreciate
feedback.
I'd try to do things much more
simply than
this. Most
simply, just
assign polymorphic_identity to be
the integer
foreign key value.
Otherwise, you should be able to do
polymorphic_on on a
correlated
subquery, which itself you set up as a
column_property().
There
should be no need to modify Query or
anything like that.
I'm out of time today but if you
need more
help I
can try to
work up
an example later on.
Thanks, and keep up the great work!
SQLAlchemy
is just
magic!
--
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
<http://stackoverflow.com/help/mcve>
<http://stackoverflow.com/help/mcve
<http://stackoverflow.com/help/mcve>>
<http://stackoverflow.com/help/mcve
<http://stackoverflow.com/help/mcve>
<http://stackoverflow.com/help/mcve
<http://stackoverflow.com/help/mcve>>>
<http://stackoverflow.com/help/mcve
<http://stackoverflow.com/help/mcve>
<http://stackoverflow.com/help/mcve
<http://stackoverflow.com/help/mcve>>
<http://stackoverflow.com/help/mcve
<http://stackoverflow.com/help/mcve>
<http://stackoverflow.com/help/mcve
<http://stackoverflow.com/help/mcve>>>>
<http://stackoverflow.com/help/mcve
<http://stackoverflow.com/help/mcve>
<http://stackoverflow.com/help/mcve
<http://stackoverflow.com/help/mcve>>
<http://stackoverflow.com/help/mcve
<http://stackoverflow.com/help/mcve>
<http://stackoverflow.com/help/mcve
<http://stackoverflow.com/help/mcve>>>
<http://stackoverflow.com/help/mcve
<http://stackoverflow.com/help/mcve>
<http://stackoverflow.com/help/mcve
<http://stackoverflow.com/help/mcve>>
<http://stackoverflow.com/help/mcve
<http://stackoverflow.com/help/mcve>
<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+unsubscr...@googlegroups.com
<mailto:sqlalchemy%2bunsubscr...@googlegroups.com>
<mailto:sqlalchemy%2bunsubscr...@googlegroups.com
<mailto:sqlalchemy%252bunsubscr...@googlegroups.com>>
<mailto:sqlalchemy%2bunsubscr...@googlegroups.com
<mailto:sqlalchemy%252bunsubscr...@googlegroups.com>
<mailto:sqlalchemy%252bunsubscr...@googlegroups.com
<mailto:sqlalchemy%25252bunsubscr...@googlegroups.com>>>
<mailto:sqlalchemy%2bunsubscr...@googlegroups.com
<mailto:sqlalchemy%252bunsubscr...@googlegroups.com>
<mailto:sqlalchemy%252bunsubscr...@googlegroups.com
<mailto:sqlalchemy%25252bunsubscr...@googlegroups.com>>
<mailto:sqlalchemy%252bunsubscr...@googlegroups.com
<mailto:sqlalchemy%25252bunsubscr...@googlegroups.com>
<mailto:sqlalchemy%25252bunsubscr...@googlegroups.com
<mailto:sqlalchemy%2525252bunsubscr...@googlegroups.com>>>>
<mailto:sqlalchemy%2bunsubscr...@googlegroups.com
<mailto:sqlalchemy%252bunsubscr...@googlegroups.com>
<mailto:sqlalchemy%252bunsubscr...@googlegroups.com
<mailto:sqlalchemy%25252bunsubscr...@googlegroups.com>>
<mailto:sqlalchemy%252bunsubscr...@googlegroups.com
<mailto:sqlalchemy%25252bunsubscr...@googlegroups.com>
<mailto:sqlalchemy%25252bunsubscr...@googlegroups.com
<mailto:sqlalchemy%2525252bunsubscr...@googlegroups.com>>>
<mailto:sqlalchemy%252bunsubscr...@googlegroups.com
<mailto:sqlalchemy%25252bunsubscr...@googlegroups.com>
<mailto:sqlalchemy%25252bunsubscr...@googlegroups.com
<mailto:sqlalchemy%2525252bunsubscr...@googlegroups.com>>
<mailto:sqlalchemy%25252bunsubscr...@googlegroups.com
<mailto:sqlalchemy%2525252bunsubscr...@googlegroups.com>
<mailto:sqlalchemy%2525252bunsubscr...@googlegroups.com
<mailto:sqlalchemy%252525252bunsubscr...@googlegroups.com>>>>>
<mailto:sqlalchemy+unsubscr...@googlegroups.com
<mailto:sqlalchemy%2bunsubscr...@googlegroups.com>
<mailto:sqlalchemy%2bunsubscr...@googlegroups.com
<mailto:sqlalchemy%252bunsubscr...@googlegroups.com>>
<mailto:sqlalchemy%2bunsubscr...@googlegroups.com
<mailto:sqlalchemy%252bunsubscr...@googlegroups.com>
<mailto:sqlalchemy%252bunsubscr...@googlegroups.com
<mailto:sqlalchemy%25252bunsubscr...@googlegroups.com>>>
<mailto:sqlalchemy%2bunsubscr...@googlegroups.com
<mailto:sqlalchemy%252bunsubscr...@googlegroups.com>
<mailto:sqlalchemy%252bunsubscr...@googlegroups.com
<mailto:sqlalchemy%25252bunsubscr...@googlegroups.com>>
<mailto:sqlalchemy%252bunsubscr...@googlegroups.com
<mailto:sqlalchemy%25252bunsubscr...@googlegroups.com>
<mailto:sqlalchemy%25252bunsubscr...@googlegroups.com
<mailto:sqlalchemy%2525252bunsubscr...@googlegroups.com>>>>
<mailto:sqlalchemy%2bunsubscr...@googlegroups.com
<mailto:sqlalchemy%252bunsubscr...@googlegroups.com>
<mailto:sqlalchemy%252bunsubscr...@googlegroups.com
<mailto:sqlalchemy%25252bunsubscr...@googlegroups.com>>
<mailto:sqlalchemy%252bunsubscr...@googlegroups.com
<mailto:sqlalchemy%25252bunsubscr...@googlegroups.com>
<mailto:sqlalchemy%25252bunsubscr...@googlegroups.com
<mailto:sqlalchemy%2525252bunsubscr...@googlegroups.com>>>
<mailto:sqlalchemy%252bunsubscr...@googlegroups.com
<mailto:sqlalchemy%25252bunsubscr...@googlegroups.com>
<mailto:sqlalchemy%25252bunsubscr...@googlegroups.com
<mailto:sqlalchemy%2525252bunsubscr...@googlegroups.com>>
<mailto:sqlalchemy%25252bunsubscr...@googlegroups.com
<mailto:sqlalchemy%2525252bunsubscr...@googlegroups.com>
<mailto:sqlalchemy%2525252bunsubscr...@googlegroups.com
<mailto:sqlalchemy%252525252bunsubscr...@googlegroups.com>>>>>>.
To post to this group, send email to
sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>>>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>>>>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>>>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>>>>>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>>>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>>>>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>>>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>
<mailto:sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>>>>>>.
Visit this group at
https://groups.google.com/group/sqlalchemy
<https://groups.google.com/group/sqlalchemy>
<https://groups.google.com/group/sqlalchemy
<https://groups.google.com/group/sqlalchemy>>
<https://groups.google.com/group/sqlalchemy
<https://groups.google.com/group/sqlalchemy>
<https://groups.google.com/group/sqlalchemy
<https://groups.google.com/group/sqlalchemy>>>
<https://groups.google.com/group/sqlalchemy
<https://groups.google.com/group/sqlalchemy>
<https://groups.google.com/group/sqlalchemy
<https://groups.google.com/group/sqlalchemy>>
<https://groups.google.com/group/sqlalchemy
<https://groups.google.com/group/sqlalchemy>
<https://groups.google.com/group/sqlalchemy
<https://groups.google.com/group/sqlalchemy>>>>
<https://groups.google.com/group/sqlalchemy
<https://groups.google.com/group/sqlalchemy>
<https://groups.google.com/group/sqlalchemy
<https://groups.google.com/group/sqlalchemy>>
<https://groups.google.com/group/sqlalchemy
<https://groups.google.com/group/sqlalchemy>
<https://groups.google.com/group/sqlalchemy
<https://groups.google.com/group/sqlalchemy>>>
<https://groups.google.com/group/sqlalchemy
<https://groups.google.com/group/sqlalchemy>
<https://groups.google.com/group/sqlalchemy
<https://groups.google.com/group/sqlalchemy>>
<https://groups.google.com/group/sqlalchemy
<https://groups.google.com/group/sqlalchemy>
<https://groups.google.com/group/sqlalchemy
<https://groups.google.com/group/sqlalchemy>>>>>.
For more options, visit
https://groups.google.com/d/optout
<https://groups.google.com/d/optout>
<https://groups.google.com/d/optout
<https://groups.google.com/d/optout>>
<https://groups.google.com/d/optout
<https://groups.google.com/d/optout>
<https://groups.google.com/d/optout
<https://groups.google.com/d/optout>>>
<https://groups.google.com/d/optout
<https://groups.google.com/d/optout>
<https://groups.google.com/d/optout
<https://groups.google.com/d/optout>>
<https://groups.google.com/d/optout
<https://groups.google.com/d/optout>
<https://groups.google.com/d/optout
<https://groups.google.com/d/optout>>>>
<https://groups.google.com/d/optout
<https://groups.google.com/d/optout>
<https://groups.google.com/d/optout
<https://groups.google.com/d/optout>>
<https://groups.google.com/d/optout
<https://groups.google.com/d/optout>
<https://groups.google.com/d/optout
<https://groups.google.com/d/optout>>>
<https://groups.google.com/d/optout
<https://groups.google.com/d/optout>
<https://groups.google.com/d/optout
<https://groups.google.com/d/optout>>
<https://groups.google.com/d/optout
<https://groups.google.com/d/optout>
<https://groups.google.com/d/optout
<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
<http://stackoverflow.com/help/mcve>
<http://stackoverflow.com/help/mcve
<http://stackoverflow.com/help/mcve>>
<http://stackoverflow.com/help/mcve
<http://stackoverflow.com/help/mcve>
<http://stackoverflow.com/help/mcve
<http://stackoverflow.com/help/mcve>>>
<http://stackoverflow.com/help/mcve
<http://stackoverflow.com/help/mcve>
<http://stackoverflow.com/help/mcve
<http://stackoverflow.com/help/mcve>>
<http://stackoverflow.com/help/mcve
<http://stackoverflow.com/help/mcve>
<http://stackoverflow.com/help/mcve
<http://stackoverflow.com/help/mcve>>>>
<http://stackoverflow.com/help/mcve
<http://stackoverflow.com/help/mcve>
<http://stackoverflow.com/help/mcve
<http://stackoverflow.com/help/mcve>>
<http://stackoverflow.com/help/mcve
<http://stackoverflow.com/help/mcve>
--
-=Tucker A. Beck=-
Illustrious Writer
Devious Coder
Last Hope for the Free World
Also, Modest
--
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
<mailto:sqlalchemy+unsubscr...@googlegroups.com>.
To post to this group, send email to sqlalchemy@googlegroups.com
<mailto: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.