]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
initial work on column reflect
authorMike Bayer <mike_mp@zzzcomputing.com>
Mon, 14 Mar 2011 20:36:08 +0000 (16:36 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 14 Mar 2011 20:36:08 +0000 (16:36 -0400)
lib/sqlalchemy/engine/reflection.py
lib/sqlalchemy/events.py
lib/sqlalchemy/schema.py

index 00b2fd1bf18c051fd0d1db51b6612a247abf9ee2..72eb27c4eb8288c505b55779ab9bf0e09231bdbf 100644 (file)
@@ -381,6 +381,8 @@ class Inspector(object):
         found_table = False
         for col_d in self.get_columns(table_name, schema, **tblkw):
             found_table = True
+            table.dispatch.column_reflect(table, col_d)
+
             name = col_d['name']
             if include_columns and name not in include_columns:
                 continue
@@ -389,10 +391,9 @@ class Inspector(object):
             col_kw = {
                 'nullable':col_d['nullable'],
             }
-            if 'autoincrement' in col_d:
-                col_kw['autoincrement'] = col_d['autoincrement']
-            if 'quote' in col_d:
-                col_kw['quote'] = col_d['quote']
+            for k in ('autoincrement', 'quote', 'info', 'key'):
+                if k in col_d:
+                    col_kw[k] = col_d[k]
 
             colargs = []
             if col_d.get('default') is not None:
index 6435ff3f2ea1d14a15190a102d9becb137f66f96..e29e7c2d839444410a2894b677c78318db1d0a6c 100644 (file)
@@ -159,6 +159,56 @@ class DDLEvents(event.Events):
         
         """
 
+    def column_reflect(self, table, column_info):
+        """Called for each unit of 'column info' retrieved when
+        a :class:`.Table` is being reflected.   
+        
+        The dictionary of column information as returned by the
+        dialect is passed, and can be modified.  The dictionary
+        is that returned in each element of the list returned 
+        by :meth:`.reflection.Inspector.get_columns`. 
+        
+        The event is called before any action is taken against
+        this dictionary, and the contents can be modified.
+        The :class:`.Column` specific arguments `info`, `key`,
+        and `quote` can also be added to the dictionary and
+        will be passed to the constructor of :class:`.Column`.
+
+        Note that this event is only meaningful if either
+        associated with the :class:`.Table` class across the 
+        board, e.g.::
+        
+            from sqlalchemy.schema import Table
+            from sqlalchemy import event
+
+            def listen_for_reflect(table, column_info):
+                "receive a column_reflect event"
+                # ...
+                
+            event.listen(
+                    Table, 
+                    'column_reflect', 
+                    listen_for_reflect)
+                
+        ...or with a specific :class:`.Table` instance using
+        the ``listeners`` argument::
+        
+            def listen_for_reflect(table, column_info):
+                "receive a column_reflect event"
+                # ...
+                
+            t = Table(
+                'sometable', 
+                autoload=True,
+                listeners=[
+                    ('column_reflect', listen_for_reflect)
+                ])
+        
+        This because the reflection process initiated by ``autoload=True``
+        completes within the scope of the constructor for :class:`.Table`.
+        
+        """
+
 class SchemaEventTarget(object):
     """Base class for elements that are the targets of :class:`.DDLEvents` events.
     
index 68e8179f94d0de3c437a946bb21ed2264d5c5728..d1eb12f4f8e38563fc3fc9fc427b5c59eff03af1 100644 (file)
@@ -141,6 +141,23 @@ class Table(SchemaItem, expression.TableClause):
     :param info: A dictionary which defaults to ``{}``.  A space to store
         application specific data. This must be a dictionary.
 
+    :param listeners: A list of tuples of the form ``(<eventname>, <fn>)``
+        which will be passed to :func:`.event.listen` upon construction. 
+        This alternate hook to :func:`.event.listen` allows the establishment
+        of a listener function specific to this :class:`.Table` before 
+        the "autoload" process begins.  Particularly useful for
+        the :meth:`.events.column_reflect` event::
+        
+            def listen_for_reflect(table, column_info):
+                # ...
+                
+            t = Table(
+                'sometable', 
+                autoload=True,
+                listeners=[
+                    ('column_reflect', listen_for_reflect)
+                ])
+
     :param mustexist: When ``True``, indicates that this Table must already 
         be present in the given :class:`MetaData`` collection.
 
@@ -240,6 +257,10 @@ class Table(SchemaItem, expression.TableClause):
         self.quote_schema = kwargs.pop('quote_schema', None)
         if 'info' in kwargs:
             self.info = kwargs.pop('info')
+        if 'listeners' in kwargs:
+            listeners = kwargs.pop('listeners')
+            for evt, fn in listeners:
+                event.listen(self, evt, fn)
 
         self._prefixes = kwargs.pop('prefixes', [])