Am Samstag, 10. September 2016 09:02:32 UTC+2 schrieb Dominik George:
>
> Hi Mike,
>
> here it is. See attached mwe.py.
>


Which is here ;).

-nik 

-- 
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.
from sqlalchemy import create_engine, Column, ForeignKey, Integer, Unicode
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import backref, relationship, sessionmaker
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.orm.collections import attribute_mapped_collection
from sqlalchemy.orm import sessionmaker, scoped_session

def monkey_patch_sqlalchemy():
    from sqlalchemy.ext.associationproxy import AssociationProxy
    from sqlalchemy.util import memoized_property

    # Monkey patch support for chained association proxy queries into SQLAlchemy
    # https://bitbucket.org/zzzeek/sqlalchemy/issues/3769/chained-any-has-with-association-proxy
    if not hasattr(AssociationProxy, "_unwrap_target_assoc_proxy"):
        def _unwrap_target_assoc_proxy(self):
            attr = getattr(self.target_class, self.value_attr)
            if isinstance(attr, AssociationProxy):
                return attr, getattr(self.target_class, attr.target_collection)
            return None, None
        AssociationProxy._unwrap_target_assoc_proxy = memoized_property(_unwrap_target_assoc_proxy)

        orig_any = AssociationProxy.any
        def any_(self, criterion=None, **kwargs):
            target_assoc, inner = self._unwrap_target_assoc_proxy
            if target_assoc is not None:
                if target_assoc._target_is_object and target_assoc._uselist:
                    inner = inner.any(criterion=criterion, **kwargs)
                else:
                    inner = inner.has(criterion=criterion, **kwargs)
                return self._comparator.any(inner)
            orig_any(self, criterion, **kwargs)
        AssociationProxy.any = any_

        orig_has = AssociationProxy.has
        def has(self, criterion=None, **kwargs):
            target_assoc, inner = self._unwrap_target_assoc_proxy
            if target_assoc is not None:
                if target_assoc._target_is_object and target_assoc._uselist:
                    inner = inner.any(criterion=criterion, **kwargs)
                else:
                    inner = inner.has(criterion=criterion, **kwargs)
                return self._comparator.has(inner)
            orig_has(self, criterion, **kwargs)
        AssociationProxy.has = has

monkey_patch_sqlalchemy()

engine = create_engine("sqlite:///:memory:")
base = declarative_base(bind=engine)
session = scoped_session(sessionmaker(bind=engine))

class Tag(base):
    __tablename__ = "tags"

    tag_id = Column(Integer, primary_key=True)

    key = Column(Unicode(256))
    value = Column(Unicode(256))

    def __init__(self, key="", value="", **kwargs):
        self.key = key
        self.value = value
        base.__init__(self, **kwargs)

class Element(base):
    __tablename__ = "elements"

    element_id = Column(Integer, primary_key=True)
    tags = association_proxy("elements_tags", "tag_value",
                             creator=lambda k, v: ElementsTags(tag_key=k, tag_value=v))

class ElementsTags(base):
    __tablename__ = "elements_tags"

    map_id = Column(Integer, primary_key=True)

    element_id = Column(Integer, ForeignKey('elements.element_id'))
    tag_id = Column(Integer, ForeignKey('tags.tag_id'))

    element = relationship(Element, foreign_keys=[element_id],
                           backref=backref("elements_tags",
                                           collection_class=attribute_mapped_collection("tag_key"),
                                           cascade="all, delete-orphan"))

    tag = relationship(Tag, foreign_keys=[tag_id])
    tag_key = association_proxy("tag", "key")
    tag_value = association_proxy("tag", "value")

base.metadata.create_all()

e = Element()
e.tags[u"foo"] = u"bar"
e.tags[u"bang"] = u"baz"
session.add(e)
session.commit()

e = session.query(Element).one()
foo = e.tags[u"foo"]
bang = e.tags[u"bang"]
print("foo = %s , bang = %s" % (foo, bang))

Reply via email to