diff options
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r-- | lib/sqlalchemy/engine/base.py | 2 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/__init__.py | 7 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/dynamic.py | 2 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/evaluator.py | 12 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/mapper.py | 6 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/properties.py | 128 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/query.py | 6 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/scoping.py | 48 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/session.py | 2 | ||||
-rw-r--r-- | lib/sqlalchemy/sql/compiler.py | 2 |
10 files changed, 106 insertions, 109 deletions
diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index 412c3a2f6..f356a7c05 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -12,7 +12,7 @@ higher-level statement-construction, connection-management, execution and result contexts. """ -import inspect, StringIO, sys +import inspect, StringIO from sqlalchemy import exc, schema, util, types, log from sqlalchemy.sql import expression diff --git a/lib/sqlalchemy/orm/__init__.py b/lib/sqlalchemy/orm/__init__.py index 2c28be715..e789de561 100644 --- a/lib/sqlalchemy/orm/__init__.py +++ b/lib/sqlalchemy/orm/__init__.py @@ -14,18 +14,19 @@ documentation for an overview of how this module is used. from sqlalchemy.orm import exc from sqlalchemy.orm.mapper import \ - Mapper, _mapper_registry, class_mapper, object_mapper + Mapper, _mapper_registry, class_mapper from sqlalchemy.orm.interfaces import \ EXT_CONTINUE, EXT_STOP, ExtensionOption, InstrumentationManager, \ MapperExtension, PropComparator, SessionExtension +from sqlalchemy.orm.util import \ + AliasedClass as aliased, join, object_mapper, outerjoin, \ + polymorphic_union, with_parent from sqlalchemy.orm.properties import \ BackRef, ColumnProperty, ComparableProperty, CompositeProperty, \ PropertyLoader, SynonymProperty from sqlalchemy.orm import mapper as mapperlib from sqlalchemy.orm import strategies from sqlalchemy.orm.query import AliasOption, Query -from sqlalchemy.orm.util import \ - AliasedClass as aliased, join, outerjoin, polymorphic_union, with_parent from sqlalchemy.sql import util as sql_util from sqlalchemy.orm.session import Session as _Session from sqlalchemy.orm.session import object_session, sessionmaker diff --git a/lib/sqlalchemy/orm/dynamic.py b/lib/sqlalchemy/orm/dynamic.py index 08e6a57f4..93e6ea93a 100644 --- a/lib/sqlalchemy/orm/dynamic.py +++ b/lib/sqlalchemy/orm/dynamic.py @@ -17,7 +17,7 @@ import sqlalchemy.exceptions as sa_exc 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 +from sqlalchemy.orm.util import has_identity class DynaLoader(strategies.AbstractRelationLoader): diff --git a/lib/sqlalchemy/orm/evaluator.py b/lib/sqlalchemy/orm/evaluator.py index 3469a24c8..30d2e8aed 100644 --- a/lib/sqlalchemy/orm/evaluator.py +++ b/lib/sqlalchemy/orm/evaluator.py @@ -22,13 +22,13 @@ class EvaluatorCompiler(object): if not meth: raise UnevaluatableError("Cannot evaluate %s" % type(clause).__name__) return meth(clause) - + def visit_grouping(self, clause): return self.process(clause.element) - + def visit_null(self, clause): return lambda obj: None - + def visit_column(self, clause): if 'parententity' in clause._annotations: key = clause._annotations['parententity']._get_col_to_prop(clause).key @@ -36,7 +36,7 @@ class EvaluatorCompiler(object): key = clause.key get_corresponding_attr = operator.attrgetter(key) return lambda obj: get_corresponding_attr(obj) - + def visit_clauselist(self, clause): evaluators = map(self.process, clause.clauses) if clause.operator is operators.or_: @@ -59,7 +59,7 @@ class EvaluatorCompiler(object): return None return False return True - + return evaluate def visit_binary(self, clause): @@ -92,7 +92,7 @@ class EvaluatorCompiler(object): return not value return evaluate raise UnevaluatableError("Cannot evaluate %s with operator %s" % (type(clause).__name__, clause.operator)) - + def visit_bindparam(self, clause): val = clause.value return lambda obj: val diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index 03db70394..6196682dd 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -28,9 +28,9 @@ from sqlalchemy.orm.identity import IdentityManagedState from sqlalchemy.orm.interfaces import MapperProperty, EXT_CONTINUE, \ PropComparator from sqlalchemy.orm.util import \ - ExtensionCarrier, _INSTRUMENTOR, _class_to_mapper, _is_mapped_class, \ - _state_has_identity, _state_mapper, class_mapper, has_identity, \ - has_mapper, instance_str, object_mapper, state_str + ExtensionCarrier, _INSTRUMENTOR, _class_to_mapper, \ + _state_has_identity, _state_mapper, class_mapper, \ + instance_str, state_str __all__ = ( diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py index b0eb54301..b6f1c803f 100644 --- a/lib/sqlalchemy/orm/properties.py +++ b/lib/sqlalchemy/orm/properties.py @@ -14,9 +14,9 @@ attributes. from sqlalchemy import sql, util, log import sqlalchemy.exceptions as sa_exc from sqlalchemy.sql.util import ClauseAdapter, criterion_as_pairs -from sqlalchemy.sql import operators, ColumnElement, expression +from sqlalchemy.sql import operators, expression from sqlalchemy.orm import mapper, strategies, attributes, dependency, \ - object_mapper, session as sessionlib + object_mapper from sqlalchemy.orm.util import CascadeOptions, _class_to_mapper, _orm_annotate from sqlalchemy.orm.interfaces import StrategizedProperty, PropComparator, \ MapperProperty, ONETOMANY, MANYTOONE, MANYTOMANY @@ -82,7 +82,7 @@ class ColumnProperty(StrategizedProperty): def __clause_element__(self): return self.prop.columns[0]._annotate({"parententity": self.mapper}) __clause_element__ = util.cache_decorator(__clause_element__) - + def operate(self, op, *other, **kwargs): return op(self.__clause_element__(), *other, **kwargs) @@ -170,7 +170,7 @@ class SynonymProperty(MapperProperty): def do_init(self): class_ = self.parent.class_ - + self.logger.info("register managed attribute %s on class %s" % (self.key, class_.__name__)) if self.descriptor is None: class SynonymProp(object): @@ -224,22 +224,22 @@ class PropertyLoader(StrategizedProperty): of items that correspond to a related database table. """ - def __init__(self, argument, - secondary=None, primaryjoin=None, - secondaryjoin=None, entity_name=None, - foreign_keys=None, - uselist=None, - order_by=False, - backref=None, - _is_backref=False, - post_update=False, - cascade=None, - viewonly=False, lazy=True, - collection_class=None, passive_deletes=False, - passive_updates=True, remote_side=None, - enable_typechecks=True, join_depth=None, + def __init__(self, argument, + secondary=None, primaryjoin=None, + secondaryjoin=None, entity_name=None, + foreign_keys=None, + uselist=None, + order_by=False, + backref=None, + _is_backref=False, + post_update=False, + cascade=None, + viewonly=False, lazy=True, + collection_class=None, passive_deletes=False, + passive_updates=True, remote_side=None, + enable_typechecks=True, join_depth=None, strategy_class=None, _local_remote_pairs=None): - + self.uselist = uselist self.argument = argument self.entity_name = entity_name @@ -250,7 +250,7 @@ class PropertyLoader(StrategizedProperty): self.direction = None self.viewonly = viewonly self.lazy = lazy - self._foreign_keys = foreign_keys + self._foreign_keys = foreign_keys self.collection_class = collection_class self.passive_deletes = passive_deletes self.passive_updates = passive_updates @@ -262,7 +262,7 @@ class PropertyLoader(StrategizedProperty): self.__join_cache = {} self.comparator_factory = PropertyLoader.Comparator util.set_creation_order(self) - + if strategy_class: self.strategy_class = strategy_class elif self.lazy == 'dynamic': @@ -276,7 +276,7 @@ class PropertyLoader(StrategizedProperty): self.strategy_class = strategies.LazyLoader self._reverse_property = None - + if cascade is not None: self.cascade = CascadeOptions(cascade) else: @@ -298,18 +298,18 @@ class PropertyLoader(StrategizedProperty): else: self.backref = backref self._is_backref = _is_backref - + class Comparator(PropComparator): def __init__(self, prop, mapper, of_type=None): self.prop = self.property = prop self.mapper = mapper if of_type: self._of_type = _class_to_mapper(of_type) - + def parententity(self): return self.prop.parent parententity = property(parententity) - + def __clause_element__(self): return self.prop.parent._with_polymorphic_selectable @@ -318,10 +318,10 @@ class PropertyLoader(StrategizedProperty): def reverse_operate(self, op, other, **kwargs): return op(self, *other, **kwargs) - + def of_type(self, cls): return PropertyLoader.Comparator(self.prop, self.mapper, cls) - + def __eq__(self, other): if other is None: if self.prop.direction in [ONETOMANY, MANYTOMANY]: @@ -361,23 +361,23 @@ class PropertyLoader(StrategizedProperty): criterion = crit else: criterion = criterion & crit - + if sj: j = _orm_annotate(pj) & sj else: j = _orm_annotate(pj, exclude=self.prop.remote_side) - + if criterion and target_adapter: # limit this adapter to annotated only? criterion = target_adapter.traverse(criterion) - + # only have the "joined left side" of what we return be subject to Query adaption. The right # side of it is used for an exists() subquery and should not correlate or otherwise reach out # to anything in the enclosing query. if criterion: criterion = criterion._annotate({'_halt_adapt': True}) return sql.exists([1], j & criterion, from_obj=dest).correlate(source) - + def any(self, criterion=None, **kwargs): if not self.prop.uselist: raise sa_exc.InvalidRequestError("'any()' not implemented for scalar attributes. Use has().") @@ -402,7 +402,7 @@ class PropertyLoader(StrategizedProperty): def __negated_contains_or_equals(self, other): criterion = sql.and_(*[x==y for (x, y) in zip(self.prop.mapper.primary_key, self.prop.mapper.primary_key_from_instance(other))]) return ~self._criterion_exists(criterion) - + def __ne__(self, other): if other is None: if self.prop.direction == MANYTOONE: @@ -463,7 +463,7 @@ class PropertyLoader(StrategizedProperty): if dont_load: coll = attributes.init_collection(dest_state, self.key) for c in dest_list: - coll.append_without_event(c) + coll.append_without_event(c) else: getattr(dest.__class__, self.key).impl._set_iterable(dest_state, dest_list) else: @@ -481,7 +481,7 @@ class PropertyLoader(StrategizedProperty): if not type_ in self.cascade: return # only actively lazy load on the 'delete' cascade - passive = type_ != 'delete' or self.passive_deletes + passive = type_ != 'delete' or self.passive_deletes mapper = self.mapper.primary_mapper() instances = state.value_as_iterable(self.key, passive=passive) if instances: @@ -529,10 +529,10 @@ class PropertyLoader(StrategizedProperty): for attr in ('order_by', 'primaryjoin', 'secondaryjoin', 'secondary', '_foreign_keys', 'remote_side'): if callable(getattr(self, attr)): setattr(self, attr, getattr(self, attr)()) - + self._foreign_keys = util.to_set(self._foreign_keys) self.remote_side = util.to_set(self.remote_side) - + if not self.parent.concrete: for inheriting in self.parent.iterate_to_root(): if inheriting is not self.parent and inheriting._get_property(self.key, raiseerr=False): @@ -544,7 +544,7 @@ class PropertyLoader(StrategizedProperty): # TODO: remove 'self.table' self.target = self.table = self.mapper.mapped_table - + if self.cascade.delete_orphan: if self.parent.class_ is self.mapper.class_: raise sa_exc.ArgumentError("In relationship '%s', can't establish 'delete-orphan' cascade " @@ -588,7 +588,7 @@ class PropertyLoader(StrategizedProperty): return self.parent.mapped_table.c.contains_column(column) or \ self.target.c.contains_column(column) or \ self.secondary.c.contains_column(column) is not None - + def _determine_synchronize_pairs(self): if self.local_remote_pairs: @@ -596,7 +596,7 @@ class PropertyLoader(StrategizedProperty): raise sa_exc.ArgumentError("foreign_keys argument is required with _local_remote_pairs argument") self.synchronize_pairs = [] - + for l, r in self.local_remote_pairs: if r in self._foreign_keys: self.synchronize_pairs.append((l, r)) @@ -618,13 +618,13 @@ class PropertyLoader(StrategizedProperty): else: raise sa_exc.ArgumentError("Could not determine relation direction for primaryjoin condition '%s', on relation %s. " "Specify the 'foreign_keys' argument to indicate which columns on the relation are foreign." % (self.primaryjoin, self)) - + self.synchronize_pairs = eq_pairs - + if self.secondaryjoin: sq_pairs = criterion_as_pairs(self.secondaryjoin, consider_as_foreign_keys=self._foreign_keys, any_operator=self.viewonly) sq_pairs = [(l, r) for l, r in sq_pairs if (self._col_is_part_of_mappings(l) and self._col_is_part_of_mappings(r)) or r in self._foreign_keys] - + if not sq_pairs: if not self.viewonly and criterion_as_pairs(self.secondaryjoin, consider_as_foreign_keys=self._foreign_keys, any_operator=True): raise sa_exc.ArgumentError("Could not locate any equated, locally mapped column pairs for secondaryjoin condition '%s' on relation %s. " @@ -637,7 +637,7 @@ class PropertyLoader(StrategizedProperty): self.secondary_synchronize_pairs = sq_pairs else: self.secondary_synchronize_pairs = None - + self._foreign_keys = util.Set([r for l, r in self.synchronize_pairs]) if self.secondary_synchronize_pairs: self._foreign_keys.update([r for l, r in self.secondary_synchronize_pairs]) @@ -690,7 +690,7 @@ class PropertyLoader(StrategizedProperty): if self.remote_side: if self.direction is MANYTOONE: self.local_remote_pairs = [ - (r, l) for l, r in + (r, l) for l, r in criterion_as_pairs(self.primaryjoin, consider_as_referenced_keys=self.remote_side, any_operator=True) ] else: @@ -710,17 +710,17 @@ class PropertyLoader(StrategizedProperty): self.local_remote_pairs = eq_pairs elif self.remote_side: raise sa_exc.ArgumentError("remote_side argument is redundant against more detailed _local_remote_side argument.") - + for l, r in self.local_remote_pairs: - + if self.direction is ONETOMANY and not self._col_is_part_of_mappings(l): raise sa_exc.ArgumentError("Local column '%s' is not part of mapping %s. Specify remote_side argument to indicate which column lazy join condition should compare against." % (l, self.parent)) - + elif self.direction is MANYTOONE and not self._col_is_part_of_mappings(r): raise sa_exc.ArgumentError("Remote column '%s' is not part of mapping %s. Specify remote_side argument to indicate which column lazy join condition should bind." % (r, self.mapper)) - + self.local_side, self.remote_side = [util.OrderedSet(x) for x in zip(*list(self.local_remote_pairs))] - + def _post_init(self): if log.is_info_enabled(self.logger): @@ -751,10 +751,10 @@ class PropertyLoader(StrategizedProperty): def _refers_to_parent_table(self): return self.parent.mapped_table is self.target or self.parent.mapped_table is self.target - + def _is_self_referential(self): return self.mapper.common_parent(self.parent) - + def _create_joins(self, source_polymorphic=False, source_selectable=None, dest_polymorphic=False, dest_selectable=None): key = util.WeakCompositeKey(source_polymorphic, source_selectable, dest_polymorphic, dest_selectable) try: @@ -773,13 +773,13 @@ class PropertyLoader(StrategizedProperty): aliased = True else: dest_selectable = self.mapper.mapped_table - + if self._is_self_referential() and source_selectable is None: dest_selectable = dest_selectable.alias() aliased = True else: aliased = True - + aliased = aliased or bool(source_selectable) primaryjoin, secondaryjoin, secondary = self.primaryjoin, self.secondaryjoin, self.secondary @@ -799,13 +799,13 @@ class PropertyLoader(StrategizedProperty): else: if dest_selectable: primary_aliasizer = ClauseAdapter(dest_selectable, exclude=self.local_side, equivalents=self.mapper._equivalent_columns) - if source_selectable: + if source_selectable: primary_aliasizer.chain(ClauseAdapter(source_selectable, exclude=self.remote_side, equivalents=self.parent._equivalent_columns)) elif source_selectable: primary_aliasizer = ClauseAdapter(source_selectable, exclude=self.remote_side, equivalents=self.parent._equivalent_columns) secondary_aliasizer = None - + primaryjoin = primary_aliasizer.traverse(primaryjoin) target_adapter = secondary_aliasizer or primary_aliasizer target_adapter.include = target_adapter.exclude = None @@ -814,12 +814,12 @@ class PropertyLoader(StrategizedProperty): self.__join_cache[key] = ret = (primaryjoin, secondaryjoin, (source_selectable or self.parent.local_table), (dest_selectable or self.mapper.local_table), secondary, target_adapter) return ret - + def _get_join(self, parent, primary=True, secondary=True, polymorphic_parent=True): """deprecated. use primary_join_against(), secondary_join_against(), full_join_against()""" - + pj, sj, source, dest, secondarytable, adapter = self._create_joins(source_polymorphic=polymorphic_parent) - + if primary and secondary: return pj & sj elif primary: @@ -828,8 +828,8 @@ class PropertyLoader(StrategizedProperty): return sj else: raise AssertionError("illegal condition") - - + + def register_dependencies(self, uowcommit): if not self.viewonly: self._dependency_processor.register_dependencies(uowcommit) @@ -846,7 +846,7 @@ class BackRef(object): self.kwargs = kwargs self.prop = _prop self.extension = attributes.GenericBackrefExtension(self.key) - + def compile(self, prop): if self.prop: return @@ -862,8 +862,10 @@ class BackRef(object): pj = self.kwargs.pop('primaryjoin', prop.primaryjoin) sj = self.kwargs.pop('secondaryjoin', None) if sj: - raise exceptions.InvalidRequestError("Can't assign 'secondaryjoin' on a backref against a non-secondary relation.") - + raise sa_exc.InvalidRequestError( + "Can't assign 'secondaryjoin' on a backref against " + "a non-secondary relation.") + parent = prop.parent.primary_mapper() self.kwargs.setdefault('viewonly', prop.viewonly) self.kwargs.setdefault('post_update', prop.post_update) diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index 2fba04ee0..c9b2dd9aa 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -26,8 +26,8 @@ from sqlalchemy.orm import exc as orm_exc from sqlalchemy.sql import util as sql_util from sqlalchemy.sql import expression, visitors, operators from sqlalchemy.orm import attributes, interfaces, mapper, object_mapper, evaluator -from sqlalchemy.orm.util import _state_mapper, _is_mapped_class, \ - _is_aliased_class, _entity_descriptor, _entity_info, _class_to_mapper, \ +from sqlalchemy.orm.util import _is_mapped_class, \ + _is_aliased_class, _entity_descriptor, _entity_info, \ _orm_columns, AliasedClass, _orm_selectable, join as orm_join, ORMAdapter __all__ = ['Query', 'QueryContext', 'aliased'] @@ -1020,7 +1020,7 @@ class Query(object): """ if self._statement: - raise exceptions.InvalidRequestError( + raise sa_exc.InvalidRequestError( "one() not available when from_statement() is used; " "use `first()` instead.") diff --git a/lib/sqlalchemy/orm/scoping.py b/lib/sqlalchemy/orm/scoping.py index c3155c9ef..d551bc9bc 100644 --- a/lib/sqlalchemy/orm/scoping.py +++ b/lib/sqlalchemy/orm/scoping.py @@ -4,9 +4,6 @@ # This module is part of SQLAlchemy and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php -import inspect -import types - import sqlalchemy.exceptions as sa_exc from sqlalchemy.util import ScopedRegistry, to_list, get_cls_kwargs from sqlalchemy.orm import MapperExtension, EXT_CONTINUE, object_session, \ @@ -22,11 +19,11 @@ class ScopedSession(object): Usage:: Session = scoped_session(sessionmaker(autoflush=True)) - + To map classes so that new instances are saved in the current Session automatically, as well as to provide session-aware class attributes such as "query": - + mapper = Session.mapper mapper(Class, table, ...) @@ -51,48 +48,48 @@ class ScopedSession(object): return self.session_factory(**kwargs) else: return self.registry() - + def remove(self): if self.registry.has(): self.registry().close() self.registry.clear() - + def mapper(self, *args, **kwargs): """return a mapper() function which associates this ScopedSession with the Mapper.""" - + from sqlalchemy.orm import mapper - + extension_args = dict([(arg, kwargs.pop(arg)) for arg in get_cls_kwargs(_ScopedExt) if arg in kwargs]) - + kwargs['extension'] = extension = to_list(kwargs.get('extension', [])) if extension_args: extension.append(self.extension.configure(**extension_args)) else: extension.append(self.extension) return mapper(*args, **kwargs) - + def configure(self, **kwargs): """reconfigure the sessionmaker used by this ScopedSession.""" - + self.session_factory.configure(**kwargs) def query_property(self): """return a class property which produces a `Query` object against the class when called. - + e.g.:: Session = scoped_session(sessionmaker()) - + class MyClass(object): query = Session.query_property() - + # after mappers are defined result = MyClass.query.filter(MyClass.name=='foo').all() - + """ - + class query(object): def __get__(s, instance, owner): mapper = class_mapper(owner, raiseerror=False) @@ -101,7 +98,7 @@ class ScopedSession(object): else: return None return query() - + def instrument(name): def do(self, *args, **kwargs): return getattr(self.registry(), name)(*args, **kwargs) @@ -124,20 +121,20 @@ def clslevel(name): return classmethod(do) for prop in ('close_all', 'object_session', 'identity_key'): setattr(ScopedSession, prop, clslevel(prop)) - + class _ScopedExt(MapperExtension): def __init__(self, context, validate=False, save_on_init=True): self.context = context self.validate = validate self.save_on_init = save_on_init self.set_kwargs_on_init = None - + def validating(self): return _ScopedExt(self.context, validate=True) - + def configure(self, **kwargs): return _ScopedExt(self.context, **kwargs) - + def instrument_class(self, mapper, class_): class query(object): def __getattr__(s, key): @@ -146,8 +143,8 @@ class _ScopedExt(MapperExtension): return self.context.registry().query(class_) def __get__(self, instance, cls): return self - - if not 'query' in class_.__dict__: + + if not 'query' in class_.__dict__: class_.query = query() if self.set_kwargs_on_init is None: @@ -191,6 +188,3 @@ class _ScopedExt(MapperExtension): delattr(class_, '__init__') if hasattr(class_, 'query'): delattr(class_, 'query') - - - diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py index 380bc8622..0325b5eae 100644 --- a/lib/sqlalchemy/orm/session.py +++ b/lib/sqlalchemy/orm/session.py @@ -1222,7 +1222,7 @@ class Session(object): if state.key is not None: raise sa_exc.InvalidRequestError( "Object '%s' already has an identity - it can't be registered " - "as pending" % repr(obj)) + "as pending" % mapperutil.state_str(state)) self._attach(state) if state not in self._new: self._new[state] = state.obj() diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index 1edf04ee1..df5e853fa 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -18,7 +18,7 @@ creating database-specific compilers and schema generators, the module is otherwise internal to SQLAlchemy. """ -import string, re, itertools +import string, re from sqlalchemy import schema, engine, util, exc from sqlalchemy.sql import operators, functions from sqlalchemy.sql import expression as sql |