schema.Table(remote_table, table.metadata, autoload=True, autoload_with=connection, owner=remote_owner) if local_column not in fk[0]: fk[0].append(local_column) if refspec not in fk[1]: fk[1].append(refspec) for name, value in fks.iteritems(): table.append_constraint( schema.ForeignKeyConstraint(value[0], value[1], name=name)) OracleDialect.logger = logging.class_logger(OracleDialect) class _OuterJoinColumn(sql.ClauseElement): __visit_name__ = 'outer_join_column' def __init__(self, column): self.column = column class OracleCompiler(compiler.DefaultCompiler): """Oracle compiler modifies the lexical structure of Select statements to work under non-ANSI configured Oracle databases, if the use_ansi flag is False. """
if current_path and token == current_path[1]: current_path = current_path[2:] continue if prop is None: return [] path = build_path(mapper, prop.key, path) l.append(path) if getattr(token, '_of_type', None): mapper = token._of_type else: mapper = getattr(prop, 'mapper', None) return l PropertyOption.logger = logging.class_logger(PropertyOption) PropertyOption._should_log_debug = logging.is_debug_enabled( PropertyOption.logger) class AttributeExtension(object): """An abstract class which specifies `append`, `delete`, and `set` event handlers to be attached to an object property. """ def append(self, obj, child, initiator): pass def remove(self, obj, child, initiator): pass def set(self, obj, child, oldchild, initiator):
clearkeys = True else: value = self.source_mapper.get_attr_by_column( source, self.source_column) if isinstance(dest, dict): dest[self.dest_column.key] = value else: if clearkeys and self.dest_primary_key(): raise exceptions.AssertionError( "Dependency rule tried to blank-out primary key column '%s' on instance '%s'" % (str(self.dest_column), mapperutil.instance_str(dest))) if logging.is_debug_enabled(self.logger): self.logger.debug( "execute() instances: %s(%s)->%s(%s) ('%s')" % (mapperutil.instance_str(source), str(self.source_column), mapperutil.instance_str(dest), str( self.dest_column), value)) self.dest_mapper.set_attr_by_column(dest, self.dest_column, value) SyncRule.logger = logging.class_logger(SyncRule) class BinaryVisitor(visitors.ClauseVisitor): def __init__(self, func): self.func = func def visit_binary(self, binary): self.func(binary)
refspec = ".".join([remote_table, remote_column]) t = schema.Table(remote_table, table.metadata, autoload=True, autoload_with=connection, oracle_resolve_synonyms=resolve_synonyms, useexisting=True) else: refspec = ".".join([x for x in [remote_owner, remote_table, remote_column] if x]) t = schema.Table(remote_table, table.metadata, autoload=True, autoload_with=connection, schema=remote_owner, oracle_resolve_synonyms=resolve_synonyms, useexisting=True) if local_column not in fk[0]: fk[0].append(local_column) if refspec not in fk[1]: fk[1].append(refspec) for name, value in fks.iteritems(): table.append_constraint(schema.ForeignKeyConstraint(value[0], value[1], name=name)) OracleDialect.logger = logging.class_logger(OracleDialect) class _OuterJoinColumn(sql.ClauseElement): __visit_name__ = 'outer_join_column' def __init__(self, column): self.column = column def _get_from_objects(self, **kwargs): return [] class OracleCompiler(compiler.DefaultCompiler): """Oracle compiler modifies the lexical structure of Select statements to work under non-ANSI configured Oracle databases, if the use_ansi flag is False. """ operators = compiler.DefaultCompiler.operators.copy()
self.logger.debug("Returning active column fetcher for %s %s" % (mapper, self.key)) return (new_execute, None, None) else: def new_execute(instance, row, isnew, **flags): if isnew: instance._state.expire_attributes([self.key]) if self._should_log_debug: self.logger.debug("Deferring load for %s %s" % (mapper, self.key)) return (new_execute, None, None) ColumnLoader.logger = logging.class_logger(ColumnLoader) class DeferredColumnLoader(LoaderStrategy): """Deferred column loader, a per-column or per-column-group lazy loader.""" def create_row_processor(self, selectcontext, mapper, row): if self.columns[0] in row: return self.parent_property._get_strategy( ColumnLoader).create_row_processor(selectcontext, mapper, row) elif not self.is_class_level or len(selectcontext.options): def new_execute(instance, row, **flags): if self._should_log_debug: self.logger.debug( "set deferred callable on %s" % mapperutil.attribute_str(instance, self.key))
def get_col_value(self, column, value): return value class ColumnComparator(PropComparator): def clause_element(self): return self.prop.columns[0] def operate(self, op, *other, **kwargs): return op(self.prop.columns[0], *other, **kwargs) def reverse_operate(self, op, other, **kwargs): col = self.prop.columns[0] return op(col._bind_param(other), col, **kwargs) ColumnProperty.logger = logging.class_logger(ColumnProperty) class CompositeProperty(ColumnProperty): """subclasses ColumnProperty to provide composite type support.""" def __init__(self, class_, *columns, **kwargs): super(CompositeProperty, self).__init__(*columns, **kwargs) self.composite_class = class_ self.comparator = kwargs.pop('comparator', CompositeProperty.Comparator)(self) def do_init(self): super(ColumnProperty, self).do_init() # TODO: similar PK check as ColumnProperty does ? def copy(self): return CompositeProperty(deferred=self.deferred, group=self.group, composite_class=self.composite_class, *self.columns)
from sqlalchemy import exceptions, util, logging from sqlalchemy.orm import attributes, object_session, util as mapperutil, strategies from sqlalchemy.orm.query import Query from sqlalchemy.orm.mapper import has_identity, object_mapper class DynaLoader(strategies.AbstractRelationLoader): def init_class_attribute(self): self.is_class_level = True self._register_attribute(self.parent.class_, impl_class=DynamicAttributeImpl, target_mapper=self.parent_property.mapper, order_by=self.parent_property.order_by) def create_row_processor(self, selectcontext, mapper, row): return (None, None, None) DynaLoader.logger = logging.class_logger(DynaLoader) class DynamicAttributeImpl(attributes.AttributeImpl): def __init__(self, class_, key, typecallable, target_mapper, order_by, **kwargs): super(DynamicAttributeImpl, self).__init__(class_, key, typecallable, **kwargs) self.target_mapper = target_mapper self.order_by=order_by self.query_class = AppenderQuery def get(self, state, passive=False): if passive: return self._get_collection_history(state, passive=True).added_items else: return self.query_class(self, state) def get_collection(self, state, user_data=None, passive=True):
# additional entities/columns, add those to selection criterion for m in self._entities: if isinstance(m, type): m = mapper.class_mapper(m) if isinstance(m, mapper.Mapper): for value in m.iterate_properties: value.setup(context) elif isinstance(m, sql.ColumnElement): statement.append_column(m) return statement def __log_debug(self, msg): self.logger.debug(msg) Query.logger = logging.class_logger(Query) class QueryContext(OperationContext): """Created within the ``Query.compile()`` method to store and share state among all the Mappers and MapperProperty objects used in a query construction. """ def __init__(self, query, kwargs): self.query = query self.order_by = kwargs.pop('order_by', query._order_by) self.group_by = kwargs.pop('group_by', query._group_by) self.from_obj = kwargs.pop('from_obj', query._from_obj) self.lockmode = kwargs.pop('lockmode', query.lockmode) self.distinct = kwargs.pop('distinct', query._distinct) self.limit = kwargs.pop('limit', query._limit)
obj._state['modified'] = True if self.trackparent and value is not None: self.sethasparent(value, True) for ext in self.extensions: ext.append(event or self, obj, value) def remove_event(self, event, obj, value): """Called by ``InstrumentedList`` when an item is removed.""" obj._state['modified'] = True if self.trackparent and value is not None: self.sethasparent(value, False) for ext in self.extensions: ext.delete(event or self, obj, value) InstrumentedAttribute.logger = logging.class_logger(InstrumentedAttribute) class InstrumentedList(object): """Instrument a list-based attribute. All mutator operations (i.e. append, remove, etc.) will fire off events to the ``InstrumentedAttribute`` that manages the object's attribute. Those events in turn trigger things like backref operations and whatever is implemented by ``do_list_value_changed`` on ``InstrumentedAttribute``. Note that this list does a lot less than earlier versions of SA list-based attributes, which used ``HistoryArraySet``. This list wrapper does **not** maintain setlike semantics, meaning you can add as many duplicates as you want (which can break a lot of SQL), and also does not do anything related to history tracking.
from sqlalchemy.orm.mapper import has_identity, object_mapper class DynaLoader(strategies.AbstractRelationLoader): def init_class_attribute(self): self.is_class_level = True self._register_attribute(self.parent.class_, impl_class=DynamicAttributeImpl, target_mapper=self.parent_property.mapper, order_by=self.parent_property.order_by) def create_row_processor(self, selectcontext, mapper, row): return (None, None, None) DynaLoader.logger = logging.class_logger(DynaLoader) class DynamicAttributeImpl(attributes.AttributeImpl): def __init__(self, class_, key, typecallable, target_mapper, order_by, **kwargs): super(DynamicAttributeImpl, self).__init__(class_, key, typecallable, **kwargs) self.target_mapper = target_mapper self.order_by = order_by self.query_class = AppenderQuery def get(self, state, passive=False): if passive: return self._get_collection_history(state, passive=True).added_items
if self.trackparent and value is not None: self.sethasparent(value, True) for ext in self.extensions: ext.append(event or self, obj, value) def remove_event(self, event, obj, value): """Called by ``InstrumentedList`` when an item is removed.""" obj._state['modified'] = True if self.trackparent and value is not None: self.sethasparent(value, False) for ext in self.extensions: ext.delete(event or self, obj, value) InstrumentedAttribute.logger = logging.class_logger(InstrumentedAttribute) class InstrumentedList(object): """Instrument a list-based attribute. All mutator operations (i.e. append, remove, etc.) will fire off events to the ``InstrumentedAttribute`` that manages the object's attribute. Those events in turn trigger things like backref operations and whatever is implemented by ``do_list_value_changed`` on ``InstrumentedAttribute``. Note that this list does a lot less than earlier versions of SA list-based attributes, which used ``HistoryArraySet``. This list wrapper does **not** maintain setlike semantics, meaning you can add as many duplicates as you want (which can break a lot of SQL), and
if not self.omit_schema and use_schema and getattr(table, 'schema', None): return (self.quote_identifier(table.schema), self.format_table(table, use_schema=False)) else: return (self.format_table(table, use_schema=False), ) def unformat_identifiers(self, identifiers): """Unpack 'schema.table.column'-like strings into components.""" try: r = self._r_identifiers except AttributeError: initial, final, escaped_final = \ [re.escape(s) for s in (self.initial_quote, self.final_quote, self._escape_identifier(self.final_quote))] r = re.compile( r'(?:' r'(?:%(initial)s((?:%(escaped)s|[^%(final)s])+)%(final)s' r'|([^\.]+))(?=\.|$))+' % { 'initial': initial, 'final': final, 'escaped': escaped_final }) self._r_identifiers = r return [self._unescape_identifier(i) for i in [a or b for a, b in r.findall(identifiers)]] IdentifierPreparer.logger = logging.class_logger(IdentifierPreparer)
def execute(self, source, dest, obj, child, clearkeys): if source is None: if self.issecondary is False: source = obj elif self.issecondary is True: source = child if clearkeys or source is None: value = None clearkeys = True else: value = self.source_mapper.get_attr_by_column(source, self.source_column) if isinstance(dest, dict): dest[self.dest_column.key] = value else: if clearkeys and self.dest_primary_key(): raise exceptions.AssertionError("Dependency rule tried to blank-out primary key column '%s' on instance '%s'" % (str(self.dest_column), mapperutil.instance_str(dest))) if logging.is_debug_enabled(self.logger): self.logger.debug("execute() instances: %s(%s)->%s(%s) ('%s')" % (mapperutil.instance_str(source), str(self.source_column), mapperutil.instance_str(dest), str(self.dest_column), value)) self.dest_mapper.set_attr_by_column(dest, self.dest_column, value) SyncRule.logger = logging.class_logger(SyncRule) class BinaryVisitor(sql.ClauseVisitor): def __init__(self, func): self.func = func def visit_binary(self, binary): self.func(binary)
def new_execute(instance, row, **flags): if self._should_log_debug: self.logger.debug("populating %s with %s/%s" % (mapperutil.attribute_str(instance, self.key), row.__class__.__name__, self.columns[0].key)) instance.__dict__[self.key] = row[self.columns[0]] if self._should_log_debug: self.logger.debug("Returning active column fetcher for %s %s" % (mapper, self.key)) return (new_execute, None, None) else: def new_execute(instance, row, isnew, **flags): if isnew: instance._state.expire_attributes([self.key]) if self._should_log_debug: self.logger.debug("Deferring load for %s %s" % (mapper, self.key)) return (new_execute, None, None) ColumnLoader.logger = logging.class_logger(ColumnLoader) class DeferredColumnLoader(LoaderStrategy): """Deferred column loader, a per-column or per-column-group lazy loader.""" def create_row_processor(self, selectcontext, mapper, row): if self.columns[0] in row: return self.parent_property._get_strategy(ColumnLoader).create_row_processor(selectcontext, mapper, row) elif not self.is_class_level or len(selectcontext.options): def new_execute(instance, row, **flags): if self._should_log_debug: self.logger.debug("set deferred callable on %s" % mapperutil.attribute_str(instance, self.key)) instance._state.set_callable(self.key, self.setup_loader(instance)) return (new_execute, None, None) else: def new_execute(instance, row, **flags):
self.process_selection_property(context, self._get_property(context)) def _get_property(self, context): try: prop = self.__prop except AttributeError: mapper = context.mapper for token in self.key.split('.'): prop = mapper.props[token] if isinstance(prop, SynonymProperty): prop = mapper.props[prop.name] mapper = getattr(prop, 'mapper', None) self.__prop = prop return prop PropertyOption.logger = logging.class_logger(PropertyOption) class StrategizedOption(PropertyOption): """A MapperOption that affects which LoaderStrategy will be used for an operation by a StrategizedProperty. """ def process_query_property(self, context, property): self.logger.debug("applying option to QueryContext, property key '%s'" % self.key) context.attributes[(LoaderStrategy, property)] = self.get_strategy_class() def process_selection_property(self, context, property): self.logger.debug("applying option to SelectionContext, property key '%s'" % self.key) context.attributes[(LoaderStrategy, property)] = self.get_strategy_class() def get_strategy_class(self):
# additional entities/columns, add those to selection criterion for m in self._entities: if isinstance(m, type): m = mapper.class_mapper(m) if isinstance(m, mapper.Mapper): for value in m.props.values(): value.setup(context) elif isinstance(m, sql.ColumnElement): statement.append_column(m) return statement def __log_debug(self, msg): self.logger.debug(msg) Query.logger = logging.class_logger(Query) class QueryContext(OperationContext): """Created within the ``Query.compile()`` method to store and share state among all the Mappers and MapperProperty objects used in a query construction. """ def __init__(self, query, kwargs): self.query = query self.order_by = kwargs.pop('order_by', query._order_by) self.group_by = kwargs.pop('group_by', query._group_by) self.from_obj = kwargs.pop('from_obj', query._from_obj) self.lockmode = kwargs.pop('lockmode', query.lockmode) self.distinct = kwargs.pop('distinct', query._distinct) self.limit = kwargs.pop('limit', query._limit)