Skip to content

Latest commit

 

History

History
123 lines (101 loc) · 5.09 KB

File metadata and controls

123 lines (101 loc) · 5.09 KB

title: sqlalchemy.orm aliased Example Code category: page slug: sqlalchemy-orm-aliased-examples sortorder: 500031061 toc: False sidebartitle: sqlalchemy.orm aliased meta: Python example code that shows how to use the aliased callable from the sqlalchemy.orm module of the SQLAlchemy project.

aliased is a callable within the sqlalchemy.orm module of the SQLAlchemy project.

ColumnProperty, CompositeProperty, Load, Mapper, Query, RelationshipProperty, Session, SynonymProperty, attributes, backref, class_mapper, column_property, composite, interfaces, mapper, mapperlib, object_mapper, object_session, query, relationship, session, sessionmaker, and strategies are several other callables with code examples from the same sqlalchemy.orm package.

Example 1 from SQLAlchemy Mixins

SQLAlchemy Mixins (PyPI package information) is a collection of mixins useful for extending SQLAlchemy and simplifying your database-interacting code for some common use cases. SQLAlchemy Mixins is open sourced under the MIT license.

SQLAlchemy Mixins / sqlalchemy_mixins / smartquery.py

# smartquery.py
try:
    from typing import List
except ImportError:  # pragma: no cover
    pass

from collections import OrderedDict

import sqlalchemy
from sqlalchemy import asc, desc, inspect
~~from sqlalchemy.orm import aliased, contains_eager
from sqlalchemy.orm.util import AliasedClass
from sqlalchemy.sql import operators, extract

from .eagerload import _flatten_schema, _eager_expr_from_flat_schema, \
    EagerLoadMixin
from .inspection import InspectionMixin
from .utils import classproperty

RELATION_SPLITTER = '___'
OPERATOR_SPLITTER = '__'

DESC_PREFIX = '-'


def _parse_path_and_make_aliases(entity, entity_path, attrs, aliases):
    relations = {}
    for attr in attrs:
        if RELATION_SPLITTER in attr:
            relation_name, nested_attr = attr.split(RELATION_SPLITTER, 1)
            if relation_name in relations:
                relations[relation_name].append(nested_attr)
            else:
                relations[relation_name] = [nested_attr]

    for relation_name, nested_attrs in relations.items():
        path = entity_path + RELATION_SPLITTER + relation_name \
               if entity_path else relation_name
        if relation_name not in entity.relations:
            raise KeyError("Incorrect path `{}`: "
                           "{} doesnt have `{}` relationship "
                           .format(path, entity, relation_name))
        relationship = getattr(entity, relation_name)
~~        alias = aliased(relationship.property.mapper.class_)
        aliases[path] = alias, relationship
        _parse_path_and_make_aliases(alias, path, nested_attrs, aliases)


def smart_query(query, filters=None, sort_attrs=None, schema=None):
    if not filters:
        filters = {}
    if not sort_attrs:
        sort_attrs = []
    if not schema:
        schema = {}

    root_cls = query._entity_zero().class_  # for example, User or Post
    attrs = list(filters.keys()) + \
        list(map(lambda s: s.lstrip(DESC_PREFIX), sort_attrs))
    aliases = OrderedDict({})
    _parse_path_and_make_aliases(root_cls, '', attrs, aliases)

    loaded_paths = []
    for path, al in aliases.items():
        relationship_path = path.replace(RELATION_SPLITTER, '.')
        query = query.outerjoin(al[0], al[1]) \
            .options(contains_eager(relationship_path, alias=al[0]))
        loaded_paths.append(relationship_path)


## ... source file continues with no further aliased examples...