# Path: flask_restless/helpers.py
# def get_model(instance):
#     """Returns the model class of which the specified object is an instance."""
#     return type(instance)
# 
# Path: flask_restless/helpers.py
# def get_related_model(model, relationname):
#     """Gets the class of the model to which `model` is related by the attribute
#     whose name is `relationname`.
# 
#     For example, if we have the model classes ::
# 
#         class Person(Base):
#             __tablename__ = 'person'
#             id = Column(Integer, primary_key=True)
#             articles = relationship('Article')
# 
#         class Article(Base):
#             __tablename__ = 'article'
#             id = Column(Integer, primary_key=True)
#             author_id = Column(Integer, ForeignKey('person.id'))
#             author = relationship('Person')
# 
#     then ::
# 
#         >>> get_related_model(Person, 'articles')
#         <class 'Article'>
#         >>> get_related_model(Article, 'author')
#         <class 'Person'>
# 
#     This function also "sees through" association proxies and returns
#     the model of the proxied remote relation.
# 
#     """
#     mapper = sqlalchemy_inspect(model)
#     attribute = mapper.all_orm_descriptors[relationname]
#     # HACK This is required for Python 3.3 only. I'm guessing it lazily
#     # loads the attribute or something like that.
#     hasattr(model, relationname)
#     return get_related_model_from_attribute(attribute)
# 
# Path: flask_restless/helpers.py
# def primary_key_names(model):
#     """Returns a list of all the primary keys for a model.
# 
#     The returned list contains the name of each primary key as a string.
# 
#     """
#     mapper = sqlalchemy_inspect(model)
#     return [column.name for column in mapper.primary_key]
# 
# Path: flask_restless/helpers.py
# def primary_key_value(instance, as_string=False):
#     """Returns the value of the primary key field of the specified `instance`
#     of a SQLAlchemy model.
# 
#     This essentially a convenience function for::
# 
#         getattr(instance, primary_key_for(instance))
# 
#     If `as_string` is ``True``, try to coerce the return value to a string.
# 
#     """
#     result = getattr(instance, primary_key_for(instance))
#     if not as_string:
#         return result
#     try:
#         return str(result)
#     except UnicodeEncodeError:
#         return url_quote_plus(result.encode('utf-8'))
# 
# Path: flask_restless/helpers.py
# def session_query(session, model):
#     """Returns a SQLAlchemy query object for the specified `model`.
# 
#     If `model` has a ``query`` attribute already, ``model.query`` will be
#     returned. If the ``query`` attribute is callable ``model.query()`` will be
#     returned instead.
# 
#     If `model` has no such attribute, a query based on `session` will be
#     created and returned.
# 
#     """
#     if hasattr(model, 'query'):
#         if callable(model.query):
#             query = model.query()
#         else:
#             query = model.query
#         if hasattr(query, 'filter'):
#             return query
#     return session.query(model)
# 
# Path: flask_restless/search/filters.py
# def create_filters(model, filters):
#     """Returns an iterator over SQLAlchemy filter expressions.
# 
#     The objects generated by this function can be provided as the
#     positional arguments in an invocation of
#     :meth:`sqlalchemy.orm.Query.filter`.
# 
#     `model` is the SQLAlchemy model on which the filters will be
#     applied.
# 
#     `filters` is an iterable of dictionaries representing filter
#     objects, as described in the Flask-Restless documentation
#     (:ref:`filtering`).
# 
#     This function may raise :exc:`FilterParsingError` if there is a
#     problem converting a dictionary filter into an intermediate
#     representation (the :class:`.Filter` object) and
#     :exc:`FilterCreationError` if there is a problem converting the
#     intermediate representation into a SQLAlchemy expression.
# 
#     """
#     from_dict = partial(from_dictionary, model)
#     # `Filter.from_dictionary()` converts the dictionary representation
#     # of a filter object into an intermediate representation, an
#     # instance of :class:`.Filter` that facilitates the construction of
#     # the actual SQLAlchemy code in `create_filter` below.
#     filters = map(from_dict, filters)
#     # Each of these function calls may raise a FilterCreationError.
#     #
#     # TODO In Python 3.3+, this should be `yield from ...`.
#     return map(methodcaller('to_expression'), filters)


from sqlalchemy.orm import aliased
from sqlalchemy.sql import false as FALSE
from ..helpers import get_model
from ..helpers import get_related_model
from ..helpers import primary_key_names
from ..helpers import primary_key_value
from ..helpers import session_query
from .filters import create_filters
    `session` is the SQLAlchemy session in which to create the query.

    `model` is the SQLAlchemy model on which to create a query.

    `filters` is a list of filter objects. Each filter object is a
    dictionary representation of the filters to apply to the
    query. (This dictionary is provided directly to the
    :func:`.filters.create_filters` function.) For more information on
    the format of this dictionary, see :doc:`filtering`.

    `sort` is a list of pairs of the form ``(direction, fieldname)``,
    where ``direction`` is either '+' or '-' and ``fieldname`` is a
    string representing an attribute of the model or a dot-separated
    relationship path (for example, 'owner.name'). If `ignorecase` is
    True, the sorting will be case-insensitive (so 'a' will precede 'B'
    instead of the default behavior in which 'B' precedes 'a').

    `group_by` is a list of dot-separated relationship paths on which to
    group the query results.

    If `_initial_query` is provided, the filters, sorting, and grouping
    will be appended to this query. Otherwise, an empty query will be
    created for the specified model.

    When building the query, filters are applied first, then sorting,
    then grouping.

    """
    query = _initial_query
    if query is None:

# Path: flask_restless/helpers.py
# def get_model(instance):
#     """Returns the model class of which the specified object is an instance."""
#     return type(instance)
# 
# Path: flask_restless/helpers.py
# def get_related_model(model, relationname):
#     """Gets the class of the model to which `model` is related by the attribute
#     whose name is `relationname`.
# 
#     For example, if we have the model classes ::
# 
#         class Person(Base):
#             __tablename__ = 'person'
#             id = Column(Integer, primary_key=True)
#             articles = relationship('Article')
# 
#         class Article(Base):
#             __tablename__ = 'article'
#             id = Column(Integer, primary_key=True)
#             author_id = Column(Integer, ForeignKey('person.id'))
#             author = relationship('Person')
# 
#     then ::
# 
#         >>> get_related_model(Person, 'articles')
#         <class 'Article'>
#         >>> get_related_model(Article, 'author')
#         <class 'Person'>
# 
#     This function also "sees through" association proxies and returns
#     the model of the proxied remote relation.
# 
#     """
#     mapper = sqlalchemy_inspect(model)
#     attribute = mapper.all_orm_descriptors[relationname]
#     # HACK This is required for Python 3.3 only. I'm guessing it lazily
#     # loads the attribute or something like that.
#     hasattr(model, relationname)
#     return get_related_model_from_attribute(attribute)
# 
# Path: flask_restless/helpers.py
# def primary_key_names(model):
#     """Returns a list of all the primary keys for a model.
# 
#     The returned list contains the name of each primary key as a string.
# 
#     """
#     mapper = sqlalchemy_inspect(model)
#     return [column.name for column in mapper.primary_key]
# 
# Path: flask_restless/helpers.py
# def primary_key_value(instance, as_string=False):
#     """Returns the value of the primary key field of the specified `instance`
#     of a SQLAlchemy model.
# 
#     This essentially a convenience function for::
# 
#         getattr(instance, primary_key_for(instance))
# 
#     If `as_string` is ``True``, try to coerce the return value to a string.
# 
#     """
#     result = getattr(instance, primary_key_for(instance))
#     if not as_string:
#         return result
#     try:
#         return str(result)
#     except UnicodeEncodeError:
#         return url_quote_plus(result.encode('utf-8'))
# 
# Path: flask_restless/helpers.py
# def session_query(session, model):
#     """Returns a SQLAlchemy query object for the specified `model`.
# 
#     If `model` has a ``query`` attribute already, ``model.query`` will be
#     returned. If the ``query`` attribute is callable ``model.query()`` will be
#     returned instead.
# 
#     If `model` has no such attribute, a query based on `session` will be
#     created and returned.
# 
#     """
#     if hasattr(model, 'query'):
#         if callable(model.query):
#             query = model.query()
#         else:
#             query = model.query
#         if hasattr(query, 'filter'):
#             return query
#     return session.query(model)
# 
# Path: flask_restless/search/filters.py
# def create_filters(model, filters):
#     """Returns an iterator over SQLAlchemy filter expressions.
# 
#     The objects generated by this function can be provided as the
#     positional arguments in an invocation of
#     :meth:`sqlalchemy.orm.Query.filter`.
# 
#     `model` is the SQLAlchemy model on which the filters will be
#     applied.
# 
#     `filters` is an iterable of dictionaries representing filter
#     objects, as described in the Flask-Restless documentation
#     (:ref:`filtering`).
# 
#     This function may raise :exc:`FilterParsingError` if there is a
#     problem converting a dictionary filter into an intermediate
#     representation (the :class:`.Filter` object) and
#     :exc:`FilterCreationError` if there is a problem converting the
#     intermediate representation into a SQLAlchemy expression.
# 
#     """
#     from_dict = partial(from_dictionary, model)
#     # `Filter.from_dictionary()` converts the dictionary representation
#     # of a filter object into an intermediate representation, an
#     # instance of :class:`.Filter` that facilitates the construction of
#     # the actual SQLAlchemy code in `create_filter` below.
#     filters = map(from_dict, filters)
#     # Each of these function calls may raise a FilterCreationError.
#     #
#     # TODO In Python 3.3+, this should be `yield from ...`.
#     return map(methodcaller('to_expression'), filters)


# Path: flask_restless/search/drivers.py
from sqlalchemy.orm import aliased
from sqlalchemy.sql import false as FALSE
from ..helpers import get_model
from ..helpers import get_related_model
from ..helpers import primary_key_names
from ..helpers import primary_key_value
from ..helpers import session_query
from .filters import create_filters

    `session` is the SQLAlchemy session in which to create the query.

    `model` is the SQLAlchemy model on which to create a query.

    `filters` is a list of filter objects. Each filter object is a
    dictionary representation of the filters to apply to the
    query. (This dictionary is provided directly to the
    :func:`.filters.create_filters` function.) For more information on
    the format of this dictionary, see :doc:`filtering`.

    `sort` is a list of pairs of the form ``(direction, fieldname)``,
    where ``direction`` is either '+' or '-' and ``fieldname`` is a
    string representing an attribute of the model or a dot-separated
    relationship path (for example, 'owner.name'). If `ignorecase` is
    True, the sorting will be case-insensitive (so 'a' will precede 'B'
    instead of the default behavior in which 'B' precedes 'a').

    `group_by` is a list of dot-separated relationship paths on which to
    group the query results.

    If `_initial_query` is provided, the filters, sorting, and grouping
    will be appended to this query. Otherwise, an empty query will be
    created for the specified model.

    When building the query, filters are applied first, then sorting,
    then grouping.

    """
    query = _initial_query
    if query is None:

        query = session_query(session, model)