def create(cls, arg, attributes=None, named_attributes=None, include_primary_key=True):
        """
        :param arg: The QueryExression to be projected
        :param attributes:  attributes to select
        :param named_attributes:  new attributes to create by renaming or computing
        :param include_primary_key:  True if the primary key must be included even if it's not in attributes.
        :return: the resulting Projection object
        """
        obj = cls()
        obj._connection = arg.connection
        named_attributes = {k: v.strip() for k, v in named_attributes.items()}  # clean up values
        obj._distinct = arg.distinct
        if include_primary_key:  # include primary key of the QueryExpression
            attributes = (list(a for a in arg.primary_key if a not in named_attributes.values()) +
                          list(a for a in attributes if a not in arg.primary_key))
        else:
            # make distinct if the primary key is not completely selected
            obj._distinct = obj._distinct or not set(arg.primary_key).issubset(
                set(attributes) | set(named_attributes.values()))
        if obj._distinct or cls._need_subquery(arg, attributes, named_attributes):
            obj._arg = Subquery.create(arg)
            obj._heading = obj._arg.heading.project(attributes, named_attributes)
            if not include_primary_key:
                obj._heading = obj._heading.extend_primary_key(attributes)
        else:
            obj._arg = arg
            obj._heading = obj._arg.heading.project(attributes, named_attributes)
            obj &= arg.restriction  # copy restriction when no subquery
        return obj
def create ( cls , arg , attributes = None , named_attributes = None , include_primary_key = True ) : obj = cls ( ) obj . _connection = arg . connection named_attributes = { k : v . strip ( ) for k , v in named_attributes . items ( ) } obj . _distinct = arg . distinct if include_primary_key : attributes = ( list ( a for a in arg . primary_key if a not in named_attributes . values ( ) ) + list ( a for a in attributes if a not in arg . primary_key ) ) else : obj . _distinct = obj . _distinct or not set ( arg . primary_key ) . issubset ( set ( attributes ) | set ( named_attributes . values ( ) ) ) if obj . _distinct or cls . _need_subquery ( arg , attributes , named_attributes ) : obj . _arg = Subquery . create ( arg ) obj . _heading = obj . _arg . heading . project ( attributes , named_attributes ) if not include_primary_key : obj . _heading = obj . _heading . extend_primary_key ( attributes ) else : obj . _arg = arg obj . _heading = obj . _arg . heading . project ( attributes , named_attributes ) obj &= arg . restriction return obj
:param arg: The QueryExression to be projected
        :param attributes:  attributes to select
        :param named_attributes:  new attributes to create by renaming or computing
        :param include_primary_key:  True if the primary key must be included even if it's not in attributes.
        :return: the resulting Projection object