コード例 #1
0
    def prepare(cls, engine):
        """Reflect all the tables and map !"""
        while cls._mapper_args:
            args, kw = cls._mapper_args.pop()
            klass = args[0]
            # autoload Table, which is already
            # present in the metadata.  This
            # will fill in db-loaded columns
            # into the existing Table object.
            if args[1] is not None:
                table = args[1]
                Table(table.name,
                      cls.metadata,
                      extend_existing=True,
                      autoload_replace=False,
                      autoload=True,
                      autoload_with=engine,
                      schema=table.schema)

            # see if we need 'inherits' in the
            # mapper args.  Declarative will have
            # skipped this since mappings weren't
            # available yet.
            for c in klass.__bases__:
                if _is_mapped_class(c):  # pragma: nocover
                    kw['inherits'] = c
                    break

            klass.__mapper__ = mapper(*args, **kw)
コード例 #2
0
    def prepare(cls, engine):
        """Reflect all the tables and map !"""
        while cls._mapper_args:
            args, kw = cls._mapper_args.pop()
            klass = args[0]
            # autoload Table, which is already
            # present in the metadata.  This
            # will fill in db-loaded columns
            # into the existing Table object.
            if args[1] is not None:
                table = args[1]
                Table(
                    table.name,
                    cls.metadata,
                    extend_existing=True,
                    autoload_replace=False,
                    autoload=True,
                    autoload_with=engine,
                    schema=table.schema,
                )

            # see if we need 'inherits' in the
            # mapper args.  Declarative will have
            # skipped this since mappings weren't
            # available yet.
            for c in klass.__bases__:
                if _is_mapped_class(c):
                    kw["inherits"] = c
                    break

            klass.__mapper__ = mapper(*args, **kw)
コード例 #3
0
def _as_declarative(cls, classname, dict_):

    # dict_ will be a dictproxy, which we can't write to, and we need to!
    dict_ = dict(dict_)

    column_copies = {}
    potential_columns = {}
    
    mapper_args = {}
    table_args = inherited_table_args = None
    tablename = None
    parent_columns = ()
    
    for base in cls.__mro__:
        if _is_mapped_class(base):
            parent_columns = base.__table__.c.keys()
        else:
            for name,obj in vars(base).items():
                if name == '__mapper_args__':
                    if not mapper_args:
                        mapper_args = cls.__mapper_args__
                elif name == '__tablename__':
                    if not tablename:
                        tablename = cls.__tablename__
                elif name == '__table_args__':
                    if not table_args:                        
                        table_args = cls.__table_args__
                        if base is not cls:
                            inherited_table_args = True
                elif base is not cls:
                    # we're a mixin.
                    
                    if isinstance(obj, Column):
                        if obj.foreign_keys:
                            raise exceptions.InvalidRequestError(
                            "Columns with foreign keys to other columns "
                            "must be declared as @classproperty callables "
                            "on declarative mixin classes. ")
                        if name not in dict_ and not (
                                '__table__' in dict_ and 
                                name in dict_['__table__'].c
                                ):
                            potential_columns[name] = \
                                    column_copies[obj] = \
                                    obj.copy()
                            column_copies[obj]._creation_order = \
                                    obj._creation_order
                    elif isinstance(obj, MapperProperty):
                        raise exceptions.InvalidRequestError(
                            "Mapper properties (i.e. deferred,"
                            "column_property(), relationship(), etc.) must "
                            "be declared as @classproperty callables "
                            "on declarative mixin classes.")
                    elif isinstance(obj, util.classproperty):
                        dict_[name] = ret = \
                                column_copies[obj] = getattr(cls, name)
                        if isinstance(ret, (Column, MapperProperty)) and \
                            ret.doc is None:
                            ret.doc = obj.__doc__

    # apply inherited columns as we should
    for k, v in potential_columns.items():
        if tablename or k not in parent_columns:
            dict_[k] = v
            
    if inherited_table_args and not tablename:
        table_args = None

    # make sure that column copies are used rather 
    # than the original columns from any mixins
    for k, v in mapper_args.iteritems():
        mapper_args[k] = column_copies.get(v,v)
    
    cls._decl_class_registry[classname] = cls
    our_stuff = util.OrderedDict()

    for k in dict_:
        value = dict_[k]
        if isinstance(value, util.classproperty):
            value = getattr(cls, k)
            
        if (isinstance(value, tuple) and len(value) == 1 and
            isinstance(value[0], (Column, MapperProperty))):
            util.warn("Ignoring declarative-like tuple value of attribute "
                      "%s: possibly a copy-and-paste error with a comma "
                      "left at the end of the line?" % k)
            continue
        if not isinstance(value, (Column, MapperProperty)):
            continue
        prop = _deferred_relationship(cls, value)
        our_stuff[k] = prop

    # set up attributes in the order they were created
    our_stuff.sort(key=lambda key: our_stuff[key]._creation_order)

    # extract columns from the class dict
    cols = []
    for key, c in our_stuff.iteritems():
        if isinstance(c, ColumnProperty):
            for col in c.columns:
                if isinstance(col, Column) and col.table is None:
                    _undefer_column_name(key, col)
                    cols.append(col)
        elif isinstance(c, Column):
            _undefer_column_name(key, c)
            cols.append(c)
            # if the column is the same name as the key, 
            # remove it from the explicit properties dict.
            # the normal rules for assigning column-based properties
            # will take over, including precedence of columns
            # in multi-column ColumnProperties.
            if key == c.key:
                del our_stuff[key]

    table = None
    if '__table__' not in dict_:
        if tablename is not None:
            
            if isinstance(table_args, dict):
                args, table_kw = (), table_args
            elif isinstance(table_args, tuple):
                args = table_args[0:-1]
                table_kw = table_args[-1]
                if len(table_args) < 2 or not isinstance(table_kw, dict):
                    raise exceptions.ArgumentError(
                        "Tuple form of __table_args__ is "
                        "(arg1, arg2, arg3, ..., {'kw1':val1, "
                        "'kw2':val2, ...})"
                    )
            else:
                args, table_kw = (), {}

            autoload = dict_.get('__autoload__')
            if autoload:
                table_kw['autoload'] = True

            cls.__table__ = table = Table(tablename, cls.metadata,
                                          *(tuple(cols) + tuple(args)),
                                           **table_kw)
    else:
        table = cls.__table__
        if cols:
            for c in cols:
                if not table.c.contains_column(c):
                    raise exceptions.ArgumentError(
                        "Can't add additional column %r when "
                        "specifying __table__" % c.key
                    )
    
    if 'inherits' not in mapper_args:
        for c in cls.__bases__:
            if _is_mapped_class(c):
                mapper_args['inherits'] = cls._decl_class_registry.get(
                                                            c.__name__, None)
                break

    if hasattr(cls, '__mapper_cls__'):
        mapper_cls = util.unbound_method_to_callable(cls.__mapper_cls__)
    else:
        mapper_cls = mapper

    if table is None and 'inherits' not in mapper_args:
        raise exceptions.InvalidRequestError(
            "Class %r does not have a __table__ or __tablename__ "
            "specified and does not inherit from an existing "
            "table-mapped class." % cls
            )

    elif 'inherits' in mapper_args and not mapper_args.get('concrete', False):
        inherited_mapper = class_mapper(mapper_args['inherits'],
                                            compile=False)
        inherited_table = inherited_mapper.local_table
        if 'inherit_condition' not in mapper_args and table is not None:
            # figure out the inherit condition with relaxed rules
            # about nonexistent tables, to allow for ForeignKeys to
            # not-yet-defined tables (since we know for sure that our
            # parent table is defined within the same MetaData)
            mapper_args['inherit_condition'] = sql_util.join_condition(
                mapper_args['inherits'].__table__, table,
                ignore_nonexistent_tables=True)

        if table is None:
            # single table inheritance.
            # ensure no table args
            if table_args:
                raise exceptions.ArgumentError(
                    "Can't place __table_args__ on an inherited class "
                    "with no table."
                    )
        
            # add any columns declared here to the inherited table.
            for c in cols:
                if c.primary_key:
                    raise exceptions.ArgumentError(
                        "Can't place primary key columns on an inherited "
                        "class with no table."
                        )
                if c.name in inherited_table.c:
                    raise exceptions.ArgumentError(
                        "Column '%s' on class %s conflicts with "
                        "existing column '%s'" % 
                        (c, cls, inherited_table.c[c.name])
                    )
                inherited_table.append_column(c)
    
        # single or joined inheritance
        # exclude any cols on the inherited table which are not mapped on the
        # parent class, to avoid
        # mapping columns specific to sibling/nephew classes
        inherited_mapper = class_mapper(mapper_args['inherits'],
                                            compile=False)
        inherited_table = inherited_mapper.local_table
        
        if 'exclude_properties' not in mapper_args:
            mapper_args['exclude_properties'] = exclude_properties = \
                set([c.key for c in inherited_table.c
                     if c not in inherited_mapper._columntoproperty])
            exclude_properties.difference_update([c.key for c in cols])
    
    cls.__mapper__ = mapper_cls(cls, 
                                table, 
                                properties=our_stuff, 
                                **mapper_args)
コード例 #4
0
ファイル: declarative.py プロジェクト: greghaynes/xsbs
def _as_declarative(cls, classname, dict_):
    cls._decl_class_registry[classname] = cls
    our_stuff = util.OrderedDict()
    for k in dict_:
        value = dict_[k]
        if (isinstance(value, tuple) and len(value) == 1 and
            isinstance(value[0], (Column, MapperProperty))):
            util.warn("Ignoring declarative-like tuple value of attribute "
                      "%s: possibly a copy-and-paste error with a comma "
                      "left at the end of the line?" % k)
            continue
        if not isinstance(value, (Column, MapperProperty)):
            continue
        prop = _deferred_relation(cls, value)
        our_stuff[k] = prop

    # set up attributes in the order they were created
    our_stuff.sort(key=lambda key: our_stuff[key]._creation_order)

    # extract columns from the class dict
    cols = []
    for key, c in our_stuff.iteritems():
        if isinstance(c, ColumnProperty):
            for col in c.columns:
                if isinstance(col, Column) and col.table is None:
                    _undefer_column_name(key, col)
                    cols.append(col)
        elif isinstance(c, Column):
            _undefer_column_name(key, c)
            cols.append(c)
            # if the column is the same name as the key,
            # remove it from the explicit properties dict.
            # the normal rules for assigning column-based properties
            # will take over, including precedence of columns
            # in multi-column ColumnProperties.
            if key == c.key:
                del our_stuff[key]

    table = None
    if '__table__' not in cls.__dict__:
        if '__tablename__' in cls.__dict__:
            tablename = cls.__tablename__

            table_args = cls.__dict__.get('__table_args__')
            if isinstance(table_args, dict):
                args, table_kw = (), table_args
            elif isinstance(table_args, tuple):
                args = table_args[0:-1]
                table_kw = table_args[-1]
            else:
                args, table_kw = (), {}

            autoload = cls.__dict__.get('__autoload__')
            if autoload:
                table_kw['autoload'] = True

            cls.__table__ = table = Table(tablename, cls.metadata,
                                          *(tuple(cols) + tuple(args)), **table_kw)
    else:
        table = cls.__table__
        if cols:
            for c in cols:
                if not table.c.contains_column(c):
                    raise exceptions.ArgumentError("Can't add additional column %r when specifying __table__" % key)

    mapper_args = getattr(cls, '__mapper_args__', {})
    if 'inherits' not in mapper_args:
        for c in cls.__bases__:
            if _is_mapped_class(c):
                mapper_args['inherits'] = cls._decl_class_registry.get(c.__name__, None)
                break

    if hasattr(cls, '__mapper_cls__'):
        mapper_cls = util.unbound_method_to_callable(cls.__mapper_cls__)
    else:
        mapper_cls = mapper

    if not table and 'inherits' not in mapper_args:
        raise exceptions.InvalidRequestError("Class %r does not have a __table__ or __tablename__ "
                    "specified and does not inherit from an existing table-mapped class." % cls)

    elif 'inherits' in mapper_args and not mapper_args.get('concrete', False):
        inherited_mapper = class_mapper(mapper_args['inherits'], compile=False)
        inherited_table = inherited_mapper.local_table
        if 'inherit_condition' not in mapper_args and table:
            # figure out the inherit condition with relaxed rules
            # about nonexistent tables, to allow for ForeignKeys to
            # not-yet-defined tables (since we know for sure that our
            # parent table is defined within the same MetaData)
            mapper_args['inherit_condition'] = sql_util.join_condition(
                mapper_args['inherits'].__table__, table,
                ignore_nonexistent_tables=True)

        if not table:
            # single table inheritance.
            # ensure no table args
            table_args = cls.__dict__.get('__table_args__')
            if table_args is not None:
                raise exceptions.ArgumentError("Can't place __table_args__ on an inherited class with no table.")

            # add any columns declared here to the inherited table.
            for c in cols:
                if c.primary_key:
                    raise exceptions.ArgumentError("Can't place primary key columns on an inherited class with no table.")
                inherited_table.append_column(c)

        # single or joined inheritance
        # exclude any cols on the inherited table which are not mapped on the parent class, to avoid
        # mapping columns specific to sibling/nephew classes
        inherited_mapper = class_mapper(mapper_args['inherits'], compile=False)
        inherited_table = inherited_mapper.local_table

        if 'exclude_properties' not in mapper_args:
            mapper_args['exclude_properties'] = exclude_properties = \
                set([c.key for c in inherited_table.c if c not in inherited_mapper._columntoproperty])
            exclude_properties.difference_update([c.key for c in cols])

    cls.__mapper__ = mapper_cls(cls, table, properties=our_stuff, **mapper_args)
コード例 #5
0
def _as_declarative(cls, classname, dict_):
    cls._decl_class_registry[classname] = cls
    our_stuff = util.OrderedDict()
    for k in dict_:
        value = dict_[k]
        if (isinstance(value, tuple) and len(value) == 1
                and isinstance(value[0], (Column, MapperProperty))):
            util.warn("Ignoring declarative-like tuple value of attribute "
                      "%s: possibly a copy-and-paste error with a comma "
                      "left at the end of the line?" % k)
            continue
        if not isinstance(value, (Column, MapperProperty)):
            continue
        prop = _deferred_relation(cls, value)
        our_stuff[k] = prop

    # set up attributes in the order they were created
    our_stuff.sort(key=lambda key: our_stuff[key]._creation_order)

    # extract columns from the class dict
    cols = []
    for key, c in our_stuff.iteritems():
        if isinstance(c, ColumnProperty):
            for col in c.columns:
                if isinstance(col, Column) and col.table is None:
                    _undefer_column_name(key, col)
                    cols.append(col)
        elif isinstance(c, Column):
            _undefer_column_name(key, c)
            cols.append(c)
            # if the column is the same name as the key,
            # remove it from the explicit properties dict.
            # the normal rules for assigning column-based properties
            # will take over, including precedence of columns
            # in multi-column ColumnProperties.
            if key == c.key:
                del our_stuff[key]

    table = None
    if '__table__' not in cls.__dict__:
        if '__tablename__' in cls.__dict__:
            tablename = cls.__tablename__

            table_args = cls.__dict__.get('__table_args__')
            if isinstance(table_args, dict):
                args, table_kw = (), table_args
            elif isinstance(table_args, tuple):
                args = table_args[0:-1]
                table_kw = table_args[-1]
                if len(table_args) < 2 or not isinstance(table_kw, dict):
                    raise exceptions.ArgumentError(
                        "Tuple form of __table_args__ is "
                        "(arg1, arg2, arg3, ..., {'kw1':val1, 'kw2':val2, ...})"
                    )
            else:
                args, table_kw = (), {}

            autoload = cls.__dict__.get('__autoload__')
            if autoload:
                table_kw['autoload'] = True

            cls.__table__ = table = Table(tablename, cls.metadata,
                                          *(tuple(cols) + tuple(args)),
                                          **table_kw)
    else:
        table = cls.__table__
        if cols:
            for c in cols:
                if not table.c.contains_column(c):
                    raise exceptions.ArgumentError(
                        "Can't add additional column %r when specifying __table__"
                        % key)

    mapper_args = getattr(cls, '__mapper_args__', {})
    if 'inherits' not in mapper_args:
        for c in cls.__bases__:
            if _is_mapped_class(c):
                mapper_args['inherits'] = cls._decl_class_registry.get(
                    c.__name__, None)
                break

    if hasattr(cls, '__mapper_cls__'):
        mapper_cls = util.unbound_method_to_callable(cls.__mapper_cls__)
    else:
        mapper_cls = mapper

    if not table and 'inherits' not in mapper_args:
        raise exceptions.InvalidRequestError(
            "Class %r does not have a __table__ or __tablename__ "
            "specified and does not inherit from an existing table-mapped class."
            % cls)

    elif 'inherits' in mapper_args and not mapper_args.get('concrete', False):
        inherited_mapper = class_mapper(mapper_args['inherits'], compile=False)
        inherited_table = inherited_mapper.local_table
        if 'inherit_condition' not in mapper_args and table:
            # figure out the inherit condition with relaxed rules
            # about nonexistent tables, to allow for ForeignKeys to
            # not-yet-defined tables (since we know for sure that our
            # parent table is defined within the same MetaData)
            mapper_args['inherit_condition'] = sql_util.join_condition(
                mapper_args['inherits'].__table__,
                table,
                ignore_nonexistent_tables=True)

        if not table:
            # single table inheritance.
            # ensure no table args
            table_args = cls.__dict__.get('__table_args__')
            if table_args is not None:
                raise exceptions.ArgumentError(
                    "Can't place __table_args__ on an inherited class with no table."
                )

            # add any columns declared here to the inherited table.
            for c in cols:
                if c.primary_key:
                    raise exceptions.ArgumentError(
                        "Can't place primary key columns on an inherited class with no table."
                    )
                inherited_table.append_column(c)

        # single or joined inheritance
        # exclude any cols on the inherited table which are not mapped on the parent class, to avoid
        # mapping columns specific to sibling/nephew classes
        inherited_mapper = class_mapper(mapper_args['inherits'], compile=False)
        inherited_table = inherited_mapper.local_table

        if 'exclude_properties' not in mapper_args:
            mapper_args['exclude_properties'] = exclude_properties = \
                set([c.key for c in inherited_table.c if c not in inherited_mapper._columntoproperty])
            exclude_properties.difference_update([c.key for c in cols])

    cls.__mapper__ = mapper_cls(cls,
                                table,
                                properties=our_stuff,
                                **mapper_args)
コード例 #6
0
ファイル: declarative.py プロジェクト: clones/sqlalchemy
def _as_declarative(cls, classname, dict_):

    # doing it this way enables these attributes to be descriptors,
    # see below...
    get_mapper_args = '__mapper_args__' in dict_
    get_table_args = '__table_args__' in dict_
    
    # dict_ will be a dictproxy, which we can't write to, and we need to!
    dict_ = dict(dict_)

    column_copies = dict()

    for base in cls.__bases__:
        names = dir(base)
        if not _is_mapped_class(base):
            for name in names:
                obj = getattr(base,name)
                if isinstance(obj, Column):
                    dict_[name]=column_copies[obj]=obj.copy()
            get_mapper_args = get_mapper_args or getattr(base,'__mapper_args__',None)
            get_table_args = get_table_args or getattr(base,'__table_args__',None)
            tablename = getattr(base,'__tablename__',None)
            if tablename:
                # subtle: if tablename is a descriptor here, we actually
                # put the wrong value in, but it serves as a marker to get
                # the right value value...
                dict_['__tablename__']=tablename

    # now that we know whether or not to get these, get them from the class
    # if we should, enabling them to be decorators
    mapper_args = get_mapper_args and cls.__mapper_args__ or {}
    table_args = get_table_args and cls.__table_args__ or None
    
    # make sure that column copies are used rather than the original columns
    # from any mixins
    for k, v in mapper_args.iteritems():
        mapper_args[k] = column_copies.get(v,v)
    
    cls._decl_class_registry[classname] = cls
    our_stuff = util.OrderedDict()
    for k in dict_:
        value = dict_[k]
        if (isinstance(value, tuple) and len(value) == 1 and
            isinstance(value[0], (Column, MapperProperty))):
            util.warn("Ignoring declarative-like tuple value of attribute "
                      "%s: possibly a copy-and-paste error with a comma "
                      "left at the end of the line?" % k)
            continue
        if not isinstance(value, (Column, MapperProperty)):
            continue
        prop = _deferred_relation(cls, value)
        our_stuff[k] = prop

    # set up attributes in the order they were created
    our_stuff.sort(key=lambda key: our_stuff[key]._creation_order)

    # extract columns from the class dict
    cols = []
    for key, c in our_stuff.iteritems():
        if isinstance(c, ColumnProperty):
            for col in c.columns:
                if isinstance(col, Column) and col.table is None:
                    _undefer_column_name(key, col)
                    cols.append(col)
        elif isinstance(c, Column):
            _undefer_column_name(key, c)
            cols.append(c)
            # if the column is the same name as the key, 
            # remove it from the explicit properties dict.
            # the normal rules for assigning column-based properties
            # will take over, including precedence of columns
            # in multi-column ColumnProperties.
            if key == c.key:
                del our_stuff[key]

    table = None
    if '__table__' not in dict_:
        if '__tablename__' in dict_:
            # see above: if __tablename__ is a descriptor, this
            # means we get the right value used!
            tablename = cls.__tablename__
            
            if isinstance(table_args, dict):
                args, table_kw = (), table_args
            elif isinstance(table_args, tuple):
                args = table_args[0:-1]
                table_kw = table_args[-1]
                if len(table_args) < 2 or not isinstance(table_kw, dict):
                    raise exceptions.ArgumentError(
                                "Tuple form of __table_args__ is "
                                "(arg1, arg2, arg3, ..., {'kw1':val1, 'kw2':val2, ...})"
                            )
            else:
                args, table_kw = (), {}

            autoload = dict_.get('__autoload__')
            if autoload:
                table_kw['autoload'] = True

            cls.__table__ = table = Table(tablename, cls.metadata,
                                          *(tuple(cols) + tuple(args)), **table_kw)
    else:
        table = cls.__table__
        if cols:
            for c in cols:
                if not table.c.contains_column(c):
                    raise exceptions.ArgumentError(
                        "Can't add additional column %r when specifying __table__" % key
                        )
    
    if 'inherits' not in mapper_args:
        for c in cls.__bases__:
            if _is_mapped_class(c):
                mapper_args['inherits'] = cls._decl_class_registry.get(c.__name__, None)
                break

    if hasattr(cls, '__mapper_cls__'):
        mapper_cls = util.unbound_method_to_callable(cls.__mapper_cls__)
    else:
        mapper_cls = mapper

    if table is None and 'inherits' not in mapper_args:
        raise exceptions.InvalidRequestError(
            "Class %r does not have a __table__ or __tablename__ "
            "specified and does not inherit from an existing table-mapped class." % cls
            )

    elif 'inherits' in mapper_args and not mapper_args.get('concrete', False):
        inherited_mapper = class_mapper(mapper_args['inherits'], compile=False)
        inherited_table = inherited_mapper.local_table
        if 'inherit_condition' not in mapper_args and table is not None:
            # figure out the inherit condition with relaxed rules
            # about nonexistent tables, to allow for ForeignKeys to
            # not-yet-defined tables (since we know for sure that our
            # parent table is defined within the same MetaData)
            mapper_args['inherit_condition'] = sql_util.join_condition(
                mapper_args['inherits'].__table__, table,
                ignore_nonexistent_tables=True)

        if table is None:
            # single table inheritance.
            # ensure no table args
            if table_args is not None:
                raise exceptions.ArgumentError(
                    "Can't place __table_args__ on an inherited class with no table."
                    )
        
            # add any columns declared here to the inherited table.
            for c in cols:
                if c.primary_key:
                    raise exceptions.ArgumentError(
                        "Can't place primary key columns on an inherited class with no table."
                        )
                inherited_table.append_column(c)
    
        # single or joined inheritance
        # exclude any cols on the inherited table which are not mapped on the
        # parent class, to avoid
        # mapping columns specific to sibling/nephew classes
        inherited_mapper = class_mapper(mapper_args['inherits'], compile=False)
        inherited_table = inherited_mapper.local_table
        
        if 'exclude_properties' not in mapper_args:
            mapper_args['exclude_properties'] = exclude_properties = \
                set([c.key for c in inherited_table.c
                     if c not in inherited_mapper._columntoproperty])
            exclude_properties.difference_update([c.key for c in cols])
    
    cls.__mapper__ = mapper_cls(cls, table, properties=our_stuff, **mapper_args)