]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- added documentation for Inspector [ticket:1820]
authorMike Bayer <mike_mp@zzzcomputing.com>
Sun, 13 Jun 2010 19:49:27 +0000 (15:49 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 13 Jun 2010 19:49:27 +0000 (15:49 -0400)
- fixed "toplevel" regexp to include tokens of the form foo-bar-toplevel (i.e. multiple dashes)
- some CSS adjustment so that all API headings are in gray.

CHANGES
doc/build/builder/util.py
doc/build/metadata.rst
doc/build/reference/sqlalchemy/index.rst
doc/build/reference/sqlalchemy/inspector.rst [new file with mode: 0644]
doc/build/static/docs.css
lib/sqlalchemy/__init__.py
lib/sqlalchemy/engine/reflection.py

diff --git a/CHANGES b/CHANGES
index d0be776fe998f40bf96eb59876d6117aca25346a..b7a92783d7b91e55e19ad1779cf5c7d79cfd7e50 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -17,7 +17,10 @@ CHANGES
 - firebird
   - Fixed incorrect signature in do_execute(), error 
     introduced in 0.6.1. [ticket:1823]
-    
+
+- documentation
+  - Added documentation for the Inspector. [ticket:1820]
+  
 0.6.1
 =====
 - orm
index a7c4d6b5a387a652b28c87a7f22092a29f5feeb2..0ae4de5cd43647dece823d0f51248bb28f59fee1 100644 (file)
@@ -4,5 +4,5 @@ def striptags(text):
     return re.compile(r'<[^>]*>').sub('', text)
 
 def strip_toplevel_anchors(text):
-    return re.compile(r'\.html#\w+-toplevel').sub('.html', text)
+    return re.compile(r'\.html#[-\w]+-toplevel').sub('.html', text)
     
index 2ac0ea2a48b8d325eca360bcb44f16c77d1f83bd..6dcd625f96853ada5eb75a25be6682b6d42453be 100644 (file)
@@ -231,6 +231,8 @@ Alternatively, the ``bind`` attribute of :class:`~sqlalchemy.schema.MetaData` is
 * Your application talks to multiple database engines at different times, which use the *same* set of :class:`Table` objects.   It's usually confusing and unnecessary to begin to create "copies" of :class:`Table` objects just so that different engines can be used for different operations.  An example is an application that writes data to a "master" database while performing read-only operations from a "read slave".   A global :class:`~sqlalchemy.schema.MetaData` object is *not* appropriate for per-request switching like this, although a :class:`~sqlalchemy.schema.ThreadLocalMetaData` object is.
 * You are using the ORM :class:`Session` to handle which class/table is bound to which engine, or you are using the :class:`Session` to manage switching between engines.   Its a good idea to keep the "binding of tables to engines" in one place - either using :class:`~sqlalchemy.schema.MetaData` only (the :class:`Session` can of course be present, it just has no ``bind`` configured), or using :class:`Session` only (the ``bind`` attribute of :class:`~sqlalchemy.schema.MetaData` is left empty).
 
+.. _metadata_reflection:
+
 Reflecting Tables
 -----------------
 
@@ -303,6 +305,11 @@ The :class:`~sqlalchemy.schema.MetaData` object can also get a listing of tables
     for table in reversed(meta.sorted_tables):
         someengine.execute(table.delete())
 
+Fine Grained Reflection with Inspector
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A low level interface which provides a backend-agnostic system of loading lists of schema, table, column, and constraint descriptions from a given database is also available.  This is known as the "Inspector" and is described in the API documentation at :ref:`inspector_api_toplevel`.
+
 Specifying the Schema Name
 ---------------------------
 
index 2a3362b31a7257a6ef817213bfebc002f097328f..9970a669c07140c854ac99778ed4459490b077d1 100644 (file)
@@ -8,6 +8,7 @@ sqlalchemy
     pooling
     expressions
     schema
+    inspector
     types
     interfaces
     util
diff --git a/doc/build/reference/sqlalchemy/inspector.rst b/doc/build/reference/sqlalchemy/inspector.rst
new file mode 100644 (file)
index 0000000..e0ef914
--- /dev/null
@@ -0,0 +1,36 @@
+.. _inspector_api_toplevel:
+
+Schema Introspection
+====================
+
+.. module:: sqlalchemy.engine.reflection
+
+SQLAlchemy provides rich schema introspection capabilities.    The most common methods for this include the "autoload" argument of :class:`~sqlalchemy.schema.Table`::
+
+    from sqlalchemy import create_engine, MetaData, Table
+    engine = create_engine('...')
+    meta = MetaData()
+    user_table = Table('user', meta, autoload=True, autoload_with=engine)
+    
+As well as the :meth:`~sqlalchemy.schema.MetaData.reflect` method of :class:`~sqlalchemy.schema.MetaData`::
+
+    from sqlalchemy import create_engine, MetaData, Table
+    engine = create_engine('...')
+    meta = MetaData()
+    meta.reflect(engine)
+    user_table = meta.tables['user']
+
+Further examples of reflection using :class:`~sqlalchemy.schema.Table` and :class:`~sqlalchemy.schema.MetaData` can be found at :ref:`metadata_reflection`.
+
+There is also a low-level inspection interface available for more specific operations, known as the :class:`Inspector`::
+
+    from sqlalchemy import create_engine
+    from sqlalchemy.engine import reflection
+    engine = create_engine('...')
+    insp = reflection.Inspector.from_engine(engine)
+    print insp.get_table_names()
+
+.. autoclass:: Inspector
+    :members:
+    :undoc-members:
+    :show-inheritance:
index 33fbca52771855209bdd8e89d2b03cae486ccbbc..1df49f8b2299470acc5814b8b5dc0e4ac3143757 100644 (file)
@@ -250,6 +250,9 @@ pre {
 }
 
 dl.function > dt,
+dl.attribute > dt,
+dl.classmethod > dt,
+dl.method > dt,
 dl.class > dt
 {
     background-color:#F0F0F0;
@@ -257,6 +260,7 @@ dl.class > dt
     padding: 0px 10px;
 }
 
+
 dt:target, span.highlight {
     background-color:#FBE54E;
 }
index 4855602f3f6dce1b7c6a63685c06e817556692f4..df041574be50fce74d0b51bd4f8cb9c8d36ab823 100644 (file)
@@ -114,6 +114,6 @@ from sqlalchemy.engine import create_engine, engine_from_config
 __all__ = sorted(name for name, obj in locals().items()
                  if not (name.startswith('_') or inspect.ismodule(obj)))
                  
-__version__ = '0.6.1'
+__version__ = '0.6.2'
 
 del inspect, sys
index 4a3643a416b9435a69ac9277c5013f3df66abc15..a78dac02b79e83ca400eb09226e9dae289187a95 100644 (file)
@@ -45,14 +45,34 @@ def cache(fn, self, con, *args, **kw):
 class Inspector(object):
     """Performs database schema inspection.
 
-    The Inspector acts as a proxy to the dialects' reflection methods and
-    provides higher level functions for accessing database schema information.
+    The Inspector acts as a proxy to the reflection methods of the
+    :class:`~sqlalchemy.engine.base.Dialect`, providing a
+    consistent interface as well as caching support for previously
+    fetched metadata.
+    
+    The preferred method to construct an :class:`Inspector` is via the
+    :meth:`Inspector.from_engine` method.   I.e.::
+    
+        engine = create_engine('...')
+        insp = Inspector.from_engine(engine)
+    
+    Where above, the :class:`~sqlalchemy.engine.base.Dialect` may opt
+    to return an :class:`Inspector` subclass that provides additional
+    methods specific to the dialect's target database.
+    
     """
 
     def __init__(self, bind):
-        """Initialize the instance.
+        """Initialize a new :class:`Inspector`.
+
+        :param bind: a :class:`~sqlalchemy.engine.base.Connectable`, 
+          which is typically an instance of 
+          :class:`~sqlalchemy.engine.base.Engine` or 
+          :class:`~sqlalchemy.engine.base.Connection`.
+        
+        For a dialect-specific instance of :class:`Inspector`, see
+        :meth:`Inspector.from_engine`
 
-        :param bind: a :class:`~sqlalchemy.engine.base.Connectable`
         """
 
         # ensure initialized
@@ -70,13 +90,35 @@ class Inspector(object):
         self.info_cache = {}
 
     @classmethod
-    def from_engine(cls, engine):
-        if hasattr(engine.dialect, 'inspector'):
-            return engine.dialect.inspector(engine)
-        return Inspector(engine)
+    def from_engine(cls, bind):
+        """Construct a new dialect-specific Inspector object from the given engine or connection.
+
+        :param bind: a :class:`~sqlalchemy.engine.base.Connectable`, 
+          which is typically an instance of 
+          :class:`~sqlalchemy.engine.base.Engine` or 
+          :class:`~sqlalchemy.engine.base.Connection`.
+        
+        This method differs from direct a direct constructor call of :class:`Inspector`
+        in that the :class:`~sqlalchemy.engine.base.Dialect` is given a chance to provide
+        a dialect-specific :class:`Inspector` instance, which may provide additional
+        methods.
+        
+        See the example at :class:`Inspector`.
+        
+        """
+        if hasattr(bind.dialect, 'inspector'):
+            return bind.dialect.inspector(engine)
+        return Inspector(bind)
 
     @property
     def default_schema_name(self):
+        """Return the default schema name presented by the dialect
+        for the current engine's database user.
+        
+        E.g. this is typically ``public`` for Postgresql and ``dbo``
+        for SQL Server.
+        
+        """
         return self.dialect.default_schema_name
 
     def get_schema_names(self):
@@ -125,6 +167,11 @@ class Inspector(object):
         return tnames
 
     def get_table_options(self, table_name, schema=None, **kw):
+        """Return a dictionary of options specified when the table of the given name was created.
+        
+        This currently includes some options that apply to MySQL tables.
+        
+        """
         if hasattr(self.dialect, 'get_table_options'):
             return self.dialect.get_table_options(self.bind, table_name, schema,
                                                   info_cache=self.info_cache,
@@ -271,7 +318,25 @@ class Inspector(object):
         return indexes
 
     def reflecttable(self, table, include_columns):
-
+        """Given a Table object, load its internal constructs based on introspection.
+        
+        This is the underlying method used by most dialects to produce 
+        table reflection.  Direct usage is like::
+        
+            from sqlalchemy import create_engine, MetaData, Table
+            from sqlalchemy.engine import reflection
+            
+            engine = create_engine('...')
+            meta = MetaData()
+            user_table = Table('user', meta)
+            insp = Inspector.from_engine(engine)
+            insp.reflecttable(user_table, None)
+            
+        :param table: a :class:`~sqlalchemy.schema.Table` instance.
+        :param include_columns: a list of string column names to include
+          in the reflection process.  If ``None``, all columns are reflected.
+            
+        """
         dialect = self.bind.dialect
 
         # MySQL dialect does this.  Applicable with other dialects?