Commits

Mike Bayer committed c1fa7bc

cut down a good deal of Join construction overhead

  • Participants
  • Parent commits 0ccceaa

Comments (0)

Files changed (4)

File lib/sqlalchemy/ext/activemapper.py

     # not able to find any of the related tables
     if not defer:
         for col in klass.columns:
-            if col.foreign_key is not None:
+            if col.foreign_keys:
                 found = False
-                cn = col.foreign_key._colspec
+                cn = col.foreign_keys[0]._colspec
                 table_name = cn[:cn.rindex('.')]
                 for other_klass in ActiveMapperMeta.classes.values():
                     if other_klass.table.fullname.lower() == table_name.lower():

File lib/sqlalchemy/schema.py

         super(Column, self).__init__(name, None, type_)
         self.args = args
         self.key = kwargs.pop('key', name)
-        self._primary_key = kwargs.pop('primary_key', False)
+        self.primary_key = kwargs.pop('primary_key', False)
         self.nullable = kwargs.pop('nullable', not self.primary_key)
         self._is_oid = kwargs.pop('_is_oid', False)
         self.default = kwargs.pop('default', None)
         self.onupdate = kwargs.pop('onupdate', None)
         self.autoincrement = kwargs.pop('autoincrement', True)
         self.constraints = util.Set()
-        self._foreign_keys = util.OrderedSet()
+        self.foreign_keys = util.OrderedSet()
         if kwargs.get('info'):
             self._info = kwargs.pop('info')
         if kwargs:
             raise exceptions.ArgumentError("Unknown arguments passed to Column: " + repr(kwargs.keys()))
 
-    primary_key = util.SimpleProperty('_primary_key')
-    foreign_keys = util.SimpleProperty('_foreign_keys')
     columns = property(lambda self:[self])
 
     def __str__(self):
         kwarg = []
         if self.key != self.name:
             kwarg.append('key')
-        if self._primary_key:
+        if self.primary_key:
             kwarg.append('primary_key')
         if not self.nullable:
             kwarg.append('nullable')
 
         return table.corresponding_column(self.column, False) is not None
     
+    def get_referent(self, table):
+        """return the column in the given table referenced by this ``ForeignKey``, or
+        None if this ``ForeignKey`` does not reference the given table.
+        """
+        return table.corresponding_column(self.column, False)
+        
     def _init_column(self):
         # ForeignKey inits its remote column as late as possible, so tables can
         # be defined without dependencies

File lib/sqlalchemy/sql/expression.py

     objects using Python expressions.  See the ``_CompareMixin``
     docstring for more details.
     """
-
-    primary_key = property(lambda self:getattr(self, '_primary_key', False),
-                           doc=\
-        """Primary key flag.  Indicates if this ``Column`` represents part or 
-        whole of a primary key for its parent table.
-        """)
-    foreign_keys = property(lambda self:getattr(self, '_foreign_keys', []),
-                            doc=\
-        """Foreign key accessor.  References a list of ``ForeignKey`` objects 
-        which each represent a foreign key placed on this column's ultimate
-        ancestor.
-        """)
-
-    def _one_fkey(self):
-        if self._foreign_keys:
-            return list(self._foreign_keys)[0]
-        else:
-            return None
-
-    foreign_key = property(_one_fkey)
     
+    def __init__(self):
+        self.primary_key = False
+        self.foreign_keys = []
+
     def base_columns(self):
         if hasattr(self, '_base_columns'):
             return self._base_columns
     """
 
     def __init__(self):
+        ColumnElement.__init__(self)
         self.type = sqltypes.NULLTYPE
 
     def _get_from_objects(self, **modifiers):
 class _Cast(ColumnElement):
 
     def __init__(self, clause, totype, **kwargs):
+        ColumnElement.__init__(self)
         if not hasattr(clause, 'label'):
             clause = literal(clause)
         self.type = sqltypes.to_instance(totype)
 
 class _UnaryExpression(ColumnElement):
     def __init__(self, element, operator=None, modifier=None, type_=None, negate=None):
+        ColumnElement.__init__(self)
         self.operator = operator
         self.modifier = modifier
 
     """Represent an expression that is ``LEFT <operator> RIGHT``."""
 
     def __init__(self, left, right, operator, type_=None, negate=None):
+        ColumnElement.__init__(self)
         self.left = _literal_as_text(left).self_group(against=operator)
         self.right = _literal_as_text(right).self_group(against=operator)
         self.operator = operator
             self.onclause = onclause
         self.isouter = isouter
         self.__folded_equivalents = None
-        self._init_primary_key()
-
-    def _init_primary_key(self):
+
+    def _export_columns(self):
+        if hasattr(self, '_columns'):
+            return
+        self._columns = ColumnCollection()
+        self._foreign_keys = util.Set()
+
+        columns = list(self._flatten_exportable_columns())
+        self.__init_primary_key(columns)
+        for co in columns:
+            cp = self._proxy_column(co)
+        
+    def __init_primary_key(self, columns):
         from sqlalchemy import schema
-        pkcol = util.Set([c for c in self._flatten_exportable_columns() if c.primary_key])
+        pkcol = util.Set([c for c in columns if c.primary_key])
 
         equivs = {}
         def add_equiv(a, b):
                     omit.add(p)
                     p = c
 
-        self.__primary_key = ColumnSet([c for c in self._flatten_exportable_columns() if c.primary_key and c not in omit])
-
+        self._primary_key = ColumnSet(pkcol.difference(omit))
+        
     def description(self):
         return "Join object on %s(%d) and %s(%d)" % (self.left.description, id(self.left), self.right.description, id(self.right))
     description = property(description)
     
-    primary_key = property(lambda s:s.__primary_key)
-
     def self_group(self, against=None):
         return _FromGrouping(self)
 
-
     def _exportable_columns(self):
         return [c for c in self.left.columns] + [c for c in self.right.columns]
 
         self.right = clone(self.right)
         self.onclause = clone(self.onclause)
         self.__folded_equivalents = None
-        self._init_primary_key()
 
     def get_children(self, **kwargs):
         return self.left, self.right, self.onclause
         crit = []
         constraints = util.Set()
         for fk in secondary.foreign_keys:
-            if fk.references(primary):
-                crit.append(primary.corresponding_column(fk.column) == fk.parent)
+            col = fk.get_referent(primary)
+            if col:
+                crit.append(col == fk.parent)
                 constraints.add(fk.constraint)
-                self.foreignkey = fk.parent
         if primary is not secondary:
             for fk in primary.foreign_keys:
-                if fk.references(secondary):
-                    crit.append(secondary.corresponding_column(fk.column) == fk.parent)
+                col = fk.get_referent(secondary)
+                if col:
+                    crit.append(col == fk.parent)
                     constraints.add(fk.constraint)
-                    self.foreignkey = fk.parent
         if len(crit) == 0:
             raise exceptions.ArgumentError(
                 "Can't find any foreign key relationships "
     """
 
     def __init__(self, elem):
+        ColumnElement.__init__(self)
         self.elem = elem
         self.type = getattr(elem, 'type', None)
 
     proxies = property(lambda s:s.obj.proxies)
     base_columns = property(lambda s:s.obj.base_columns)
     proxy_set = property(lambda s:s.obj.proxy_set)
+    primary_key = property(lambda s:s.obj.primary_key)
+    foreign_keys = property(lambda s:s.obj.foreign_keys)
     
     def expression_element(self):
         return self.obj
     """
 
     def __init__(self, text, selectable=None, type_=None, _is_oid=False, is_literal=False):
+        ColumnElement.__init__(self)
         self.key = self.name = text
         self.table = selectable
         self.type = sqltypes.to_instance(type_)

File test/profiling/zoomark.py

             assert SDZ['Founded'] == datetime.date(1935, 9, 13)
     
     @testing.supported('postgres')
-    @profiling.profiled('multiview', call_range=(2720, 3055), always=True)
+    @profiling.profiled('multiview', call_range=(2400, 2600), always=True)
     def test_7_multiview(self):
         Zoo = metadata.tables['Zoo']
         Animal = metadata.tables['Animal']