Ejemplo n.º 1
0
    def test_without_default_polymorphic_buildit_newstyle(
        self, two_pjoin_fixture, use_star
    ):
        """how would we do these concrete polymorphic queries using 2.0 style,
        and not any old and esoteric features like "polymorphic_union" ?

        """
        (
            session,
            Employee,
            Engineer,
            Manager,
            Hacker,
            pjoin,
            pjoin2,
            jdoe,
            sally,
            jenn,
            hacker,
        ) = two_pjoin_fixture

        # make a union using the entities as given and wpoly from it.
        # a UNION is a UNION.  there is no way around having to write
        # out filler columns.  concrete inh is really not a good choice
        # when you need to select heterogeneously
        stmt = union_all(
            select(
                literal("engineer").label("type"),
                Engineer,
                null().label("nickname"),
            ),
            select(literal("hacker").label("type"), Hacker),
        ).subquery()

        # issue: if we make this with_polymorphic(Engineer, [Hacker], ...),
        # it blows up and tries to add the "engineer" table for unknown reasons

        if use_star:
            wp = with_polymorphic(
                Engineer, "*", stmt, polymorphic_on=stmt.c.type
            )
        else:
            wp = with_polymorphic(
                Engineer, [Engineer, Hacker], stmt, polymorphic_on=stmt.c.type
            )

        result = session.execute(select(wp)).scalars()

        eq_(
            sorted(repr(obj) for obj in result),
            [
                "Engineer Jenn knows how to program",
                "Hacker Karina 'Badass' knows how to hack",
            ],
        )
Ejemplo n.º 2
0
    def test_without_default_polymorphic_six(self, two_pjoin_fixture):
        (
            session,
            Employee,
            Engineer,
            Manager,
            Hacker,
            pjoin,
            pjoin2,
            jdoe,
            sally,
            jenn,
            hacker,
        ) = two_pjoin_fixture

        # this test is adapting what used to use from_self().
        # it's a weird test but how we would do this would be we would only
        # apply with_polymorprhic once, after we've created whatever
        # subquery we want.

        subq = pjoin2.select().subquery()

        wp2 = with_polymorphic(Engineer, "*", subq, polymorphic_on=subq.c.type)

        eq_(
            sorted([repr(x) for x in session.query(wp2)]),
            [
                "Engineer Jenn knows how to program",
                "Hacker Karina 'Badass' knows how to hack",
            ],
        )
Ejemplo n.º 3
0
    def test_without_default_polymorphic_two(self, two_pjoin_fixture):
        (
            session,
            Employee,
            Engineer,
            Manager,
            Hacker,
            pjoin,
            pjoin2,
            jdoe,
            sally,
            jenn,
            hacker,
        ) = two_pjoin_fixture
        wp = with_polymorphic(
            Employee, "*", pjoin, polymorphic_on=pjoin.c.type
        )

        eq_(
            sorted([repr(x) for x in session.query(wp)]),
            [
                "Employee Jdoe",
                "Engineer Jenn knows how to program",
                "Hacker Karina 'Badass' knows how to hack",
                "Manager Sally knows how to manage things",
            ],
        )
Ejemplo n.º 4
0
    def _get_document(self, clazz, id, clazz_locale=None, lang=None):
        """Get a document with either a single locale (if `lang is given)
        or with all locales.
        If no document exists for the given id, a `HTTPNotFound` exception is
        raised.
        """
        if not lang:
            document_query = DBSession. \
                query(clazz). \
                filter(getattr(clazz, 'document_id') == id). \
                options(joinedload('geometry'))
            document_query = add_load_for_locales(document_query, clazz,
                                                  clazz_locale)
            document_query = add_load_for_profiles(document_query, clazz)
            document = document_query.first()
        else:
            locales_type = with_polymorphic(DocumentLocale, clazz_locale) \
                if clazz_locale else DocumentLocale
            locales_attr = getattr(clazz, 'locales')
            locales_type_eager = locales_attr.of_type(clazz_locale) \
                if clazz_locale else locales_attr

            document_query = DBSession. \
                query(clazz). \
                join(locales_type). \
                filter(getattr(clazz, 'document_id') == id). \
                filter(DocumentLocale.lang == lang). \
                options(joinedload('geometry')).\
                options(contains_eager(locales_type_eager, alias=locales_type))
            document_query = add_load_for_profiles(document_query, clazz)
            document = document_query.first()

            if not document:
                # the requested locale might not be available, try to get the
                # document without locales
                document_query = DBSession. \
                    query(clazz). \
                    filter(getattr(clazz, 'document_id') == id). \
                    options(joinedload('geometry'))
                document_query = add_load_for_profiles(document_query, clazz)
                document = document_query.first()

                if document:
                    # explicitly set `locales` to an empty list so that they
                    # are no lazy loaded
                    document.locales = []
                    # also detach the document from the session, so that the
                    # empty list is not persisted
                    DBSession.expunge(document)

        if not document:
            raise HTTPNotFound('document not found')

        return document
Ejemplo n.º 5
0
    def _get_document(self, clazz, id, clazz_locale=None, lang=None):
        """Get a document with either a single locale (if `lang is given)
        or with all locales.
        If no document exists for the given id, a `HTTPNotFound` exception is
        raised.
        """
        if not lang:
            document_query = DBSession. \
                query(clazz). \
                filter(getattr(clazz, 'document_id') == id). \
                options(joinedload('geometry'))
            document_query = add_load_for_locales(
                document_query, clazz, clazz_locale)
            document_query = add_load_for_profiles(document_query, clazz)
            document = document_query.first()
        else:
            locales_type = with_polymorphic(DocumentLocale, clazz_locale) \
                if clazz_locale else DocumentLocale
            locales_attr = getattr(clazz, 'locales')
            locales_type_eager = locales_attr.of_type(clazz_locale) \
                if clazz_locale else locales_attr

            document_query = DBSession. \
                query(clazz). \
                join(locales_type). \
                filter(getattr(clazz, 'document_id') == id). \
                filter(DocumentLocale.lang == lang). \
                options(joinedload('geometry')).\
                options(contains_eager(locales_type_eager, alias=locales_type))
            document_query = add_load_for_profiles(document_query, clazz)
            document = document_query.first()

            if not document:
                # the requested locale might not be available, try to get the
                # document without locales
                document_query = DBSession. \
                    query(clazz). \
                    filter(getattr(clazz, 'document_id') == id). \
                    options(joinedload('geometry'))
                document_query = add_load_for_profiles(document_query, clazz)
                document = document_query.first()

                if document:
                    # explicitly set `locales` to an empty list so that they
                    # are no lazy loaded
                    document.locales = []
                    # also detach the document from the session, so that the
                    # empty list is not persisted
                    DBSession.expunge(document)

        if not document:
            raise HTTPNotFound('document not found')

        return document
Ejemplo n.º 6
0
    def _get_current_document(self, document_id, lang, clazz, clazz_locale):
        locales_type = with_polymorphic(DocumentLocale, clazz_locale) \
            if clazz_locale else DocumentLocale
        locales_attr = getattr(clazz, 'locales')
        locales_type_eager = locales_attr.of_type(clazz_locale) \
            if clazz_locale else locales_attr

        document_query = DBSession. \
            query(clazz). \
            join(locales_type). \
            filter(getattr(clazz, 'document_id') == document_id). \
            filter(DocumentLocale.lang == lang). \
            options(joinedload('geometry')). \
            options(contains_eager(locales_type_eager, alias=locales_type))
        return document_query.first()
Ejemplo n.º 7
0
    def _load_document_info(self, document_id, lang, clazz):
        is_route = clazz == Route
        locales_type = with_polymorphic(DocumentLocale, RouteLocale) \
            if is_route else DocumentLocale
        locales_attr = getattr(clazz, 'locales')
        locales_type_eager = locales_attr.of_type(RouteLocale) \
            if is_route else locales_attr
        locales_load_only = [
            DocumentLocale.lang, DocumentLocale.title, DocumentLocale.version
        ]
        if is_route:
            locales_load_only.append(RouteLocale.title_prefix)

        document_query = DBSession. \
            query(clazz). \
            options(load_only(
                Document.document_id, Document.version,
                Document.redirects_to, Document.protected)). \
            join(locales_type). \
            filter(getattr(clazz, 'document_id') == document_id). \
            filter(DocumentLocale.lang == lang). \
            options(contains_eager(locales_type_eager, alias=locales_type).
                    load_only(*locales_load_only))
        document_query = add_load_for_profiles(document_query, clazz)
        document = document_query.first()

        if not document:
            # the requested locale might not be available, try to get the
            # document with all locales and set the "best"
            document_query = DBSession. \
                query(clazz). \
                options(load_only(
                    Document.document_id, Document.version,
                    Document.redirects_to, Document.protected)). \
                filter(getattr(clazz, 'document_id') == document_id). \
                options(joinedload(locales_type_eager).
                        load_only(*locales_load_only))
            document_query = add_load_for_profiles(document_query, clazz)
            document = document_query.first()

            if not document:
                raise HTTPNotFound('document not found')

            set_best_locale([document], lang)

        if document.redirects_to:
            return {
                'redirects_to': document.redirects_to,
                'available_langs': get_available_langs(document.redirects_to)
            }

        assert len(document.locales) == 1
        locale = document.locales[0]

        return {
            'document_id':
            document.document_id,
            'locales': [{
                'lang':
                locale.lang,
                'title':
                locale.title if clazz != UserProfile else document.name,
                'title_prefix':
                locale.title_prefix if is_route else None
            }]
        }
Ejemplo n.º 8
0
    def _load_document_info(self, document_id, lang, clazz):
        is_route = clazz == Route
        locales_type = with_polymorphic(DocumentLocale, RouteLocale) \
            if is_route else DocumentLocale
        locales_attr = getattr(clazz, 'locales')
        locales_type_eager = locales_attr.of_type(RouteLocale) \
            if is_route else locales_attr
        locales_load_only = [
            DocumentLocale.lang, DocumentLocale.title, DocumentLocale.version]
        if is_route:
            locales_load_only.append(RouteLocale.title_prefix)

        document_query = DBSession. \
            query(clazz). \
            options(load_only(
                Document.document_id, Document.version,
                Document.redirects_to, Document.protected)). \
            join(locales_type). \
            filter(getattr(clazz, 'document_id') == document_id). \
            filter(DocumentLocale.lang == lang). \
            options(contains_eager(locales_type_eager, alias=locales_type).
                    load_only(*locales_load_only))
        document_query = add_load_for_profiles(document_query, clazz)
        document = document_query.first()

        if not document:
            # the requested locale might not be available, try to get the
            # document with all locales and set the "best"
            document_query = DBSession. \
                query(clazz). \
                options(load_only(
                    Document.document_id, Document.version,
                    Document.redirects_to, Document.protected)). \
                filter(getattr(clazz, 'document_id') == document_id). \
                options(joinedload(locales_type_eager).
                        load_only(*locales_load_only))
            document_query = add_load_for_profiles(document_query, clazz)
            document = document_query.first()

            if not document:
                raise HTTPNotFound('document not found')

            set_best_locale([document], lang)

        if document.redirects_to:
            return {
                'redirects_to': document.redirects_to,
                'available_langs': get_available_langs(
                    document.redirects_to)
            }

        assert len(document.locales) == 1
        locale = document.locales[0]

        return {
            'document_id': document.document_id,
            'locales': [{
                'lang': locale.lang,
                'title':
                    locale.title
                    if clazz != UserProfile else document.name,
                'title_prefix': locale.title_prefix if is_route else None
            }]
        }