]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- reorganize docs so expression, schema are broken out into subfiles, they're too big
authorMike Bayer <mike_mp@zzzcomputing.com>
Sun, 18 Aug 2013 22:01:27 +0000 (18:01 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 21 Aug 2013 21:05:02 +0000 (17:05 -0400)
- fix the targeting of module names moved around by using custom handlers for "Bases", etc.

cherry pick of 0c19c1c66f3a115f5ce710de571552d68fac6358 from 0.9.   there's likely issues to be fixed.

31 files changed:
doc/build/builder/autodoc_mods.py
doc/build/core/connections.rst
doc/build/core/constraints.rst [new file with mode: 0644]
doc/build/core/ddl.rst [new file with mode: 0644]
doc/build/core/defaults.rst [new file with mode: 0644]
doc/build/core/dml.rst [new file with mode: 0644]
doc/build/core/exceptions.rst
doc/build/core/expression_api.rst
doc/build/core/functions.rst [new file with mode: 0644]
doc/build/core/index.rst
doc/build/core/internals.rst
doc/build/core/metadata.rst [new file with mode: 0644]
doc/build/core/pooling.rst
doc/build/core/reflection.rst [new file with mode: 0644]
doc/build/core/schema.rst
doc/build/core/selectable.rst [new file with mode: 0644]
doc/build/core/sqlelement.rst [new file with mode: 0644]
doc/build/core/types.rst
doc/build/dialects/drizzle.rst
doc/build/dialects/mssql.rst
doc/build/dialects/mysql.rst
doc/build/dialects/oracle.rst
doc/build/dialects/postgresql.rst
doc/build/index.rst
doc/build/orm/exceptions.rst
doc/build/orm/extensions/hybrid.rst
doc/build/orm/extensions/instrumentation.rst
doc/build/orm/extensions/mutable.rst
doc/build/orm/internals.rst
doc/build/orm/session.rst
examples/inheritance/joined.py

index 576b4c3396e665018030a599a45b1cce5d29aec8..04afb03a7900873023512ee14d63a66ec9372bff 100644 (file)
@@ -9,6 +9,19 @@ def autodoc_skip_member(app, what, name, obj, skip, options):
     else:
         return skip
 
+
+def _adjust_rendered_mod_name(modname, objname):
+    modname = modname.replace("sqlalchemy.sql.sqltypes", "sqlalchemy.types")
+    modname = modname.replace("sqlalchemy.sql.type_api", "sqlalchemy.types")
+    modname = modname.replace("sqlalchemy.sql.schema", "sqlalchemy.schema")
+    modname = modname.replace("sqlalchemy.sql.elements", "sqlalchemy.sql.expression")
+    modname = modname.replace("sqlalchemy.sql.selectable", "sqlalchemy.sql.expression")
+    modname = modname.replace("sqlalchemy.sql.dml", "sqlalchemy.sql.expression")
+    modname = modname.replace("sqlalchemy.sql.ddl", "sqlalchemy.schema")
+    modname = modname.replace("sqlalchemy.sql.base", "sqlalchemy.sql.expression")
+
+    return modname
+
 # im sure this is in the app somewhere, but I don't really
 # know where, so we're doing it here.
 _track_autodoced = {}
@@ -16,6 +29,22 @@ _inherited_names = set()
 def autodoc_process_docstring(app, what, name, obj, options, lines):
     if what == "class":
         _track_autodoced[name] = obj
+
+        bases = []
+        for base in obj.__bases__:
+            if base is not object:
+                bases.append(":class:`%s.%s`" % (
+                        _adjust_rendered_mod_name(base.__module__, base.__name__),
+                        base.__name__))
+
+        if bases:
+            lines.insert(0,
+                        "Bases: %s" % (
+                            ", ".join(bases)
+                        ))
+            lines.insert(1, "")
+
+
     elif what in ("attribute", "method") and \
         options.get("inherited-members"):
         m = re.match(r'(.*?)\.([\w_]+)$', name)
@@ -35,10 +64,12 @@ def autodoc_process_docstring(app, what, name, obj, options, lines):
                         "    *inherited from the* :%s:`~%s.%s.%s` *%s of* :class:`~%s.%s`" % (
                                     "attr" if what == "attribute"
                                     else "meth",
-                                    supercls.__module__, supercls.__name__,
+                                    _adjust_rendered_mod_name(supercls.__module__, supercls.__name__),
+                                    supercls.__name__,
                                     attrname,
                                     what,
-                                    supercls.__module__, supercls.__name__
+                                    _adjust_rendered_mod_name(supercls.__module__, supercls.__name__),
+                                    supercls.__name__
                                 ),
                         ""
                     ]
@@ -51,7 +82,6 @@ def missing_reference(app, env, node, contnode):
         return None
 
 
-
 def setup(app):
     app.connect('autodoc-skip-member', autodoc_skip_member)
     app.connect('autodoc-process-docstring', autodoc_process_docstring)
index b55ca2a82eb033c7cbd9cbd39d86d4bf71622839..c05bf18d09d1750fd33f60fd30a0e0775f8c62dc 100644 (file)
@@ -495,19 +495,15 @@ Connection / Engine API
 =======================
 
 .. autoclass:: Connection
-   :show-inheritance:
    :members:
 
 .. autoclass:: Connectable
-   :show-inheritance:
    :members:
 
 .. autoclass:: Engine
-   :show-inheritance:
    :members:
 
 .. autoclass:: NestedTransaction
-    :show-inheritance:
     :members:
 
 .. autoclass:: sqlalchemy.engine.ResultProxy
@@ -517,10 +513,8 @@ Connection / Engine API
     :members:
 
 .. autoclass:: Transaction
-    :show-inheritance:
     :members:
 
 .. autoclass:: TwoPhaseTransaction
-    :show-inheritance:
     :members:
 
diff --git a/doc/build/core/constraints.rst b/doc/build/core/constraints.rst
new file mode 100644 (file)
index 0000000..75150cb
--- /dev/null
@@ -0,0 +1,383 @@
+.. _metadata_constraints_toplevel:
+.. _metadata_constraints:
+
+.. module:: sqlalchemy.schema
+
+=================================
+Defining Constraints and Indexes
+=================================
+
+.. _metadata_foreignkeys:
+
+This section will discuss SQL :term:`constraints` and indexes.  In SQLAlchemy
+the key classes include :class:`.ForeignKeyConstraint` and :class:`.Index`.
+
+Defining Foreign Keys
+---------------------
+
+A *foreign key* in SQL is a table-level construct that constrains one or more
+columns in that table to only allow values that are present in a different set
+of columns, typically but not always located on a different table. We call the
+columns which are constrained the *foreign key* columns and the columns which
+they are constrained towards the *referenced* columns. The referenced columns
+almost always define the primary key for their owning table, though there are
+exceptions to this. The foreign key is the "joint" that connects together
+pairs of rows which have a relationship with each other, and SQLAlchemy
+assigns very deep importance to this concept in virtually every area of its
+operation.
+
+In SQLAlchemy as well as in DDL, foreign key constraints can be defined as
+additional attributes within the table clause, or for single-column foreign
+keys they may optionally be specified within the definition of a single
+column. The single column foreign key is more common, and at the column level
+is specified by constructing a :class:`~sqlalchemy.schema.ForeignKey` object
+as an argument to a :class:`~sqlalchemy.schema.Column` object::
+
+    user_preference = Table('user_preference', metadata,
+        Column('pref_id', Integer, primary_key=True),
+        Column('user_id', Integer, ForeignKey("user.user_id"), nullable=False),
+        Column('pref_name', String(40), nullable=False),
+        Column('pref_value', String(100))
+    )
+
+Above, we define a new table ``user_preference`` for which each row must
+contain a value in the ``user_id`` column that also exists in the ``user``
+table's ``user_id`` column.
+
+The argument to :class:`~sqlalchemy.schema.ForeignKey` is most commonly a
+string of the form *<tablename>.<columnname>*, or for a table in a remote
+schema or "owner" of the form *<schemaname>.<tablename>.<columnname>*. It may
+also be an actual :class:`~sqlalchemy.schema.Column` object, which as we'll
+see later is accessed from an existing :class:`~sqlalchemy.schema.Table`
+object via its ``c`` collection::
+
+    ForeignKey(user.c.user_id)
+
+The advantage to using a string is that the in-python linkage between ``user``
+and ``user_preference`` is resolved only when first needed, so that table
+objects can be easily spread across multiple modules and defined in any order.
+
+Foreign keys may also be defined at the table level, using the
+:class:`~sqlalchemy.schema.ForeignKeyConstraint` object. This object can
+describe a single- or multi-column foreign key. A multi-column foreign key is
+known as a *composite* foreign key, and almost always references a table that
+has a composite primary key. Below we define a table ``invoice`` which has a
+composite primary key::
+
+    invoice = Table('invoice', metadata,
+        Column('invoice_id', Integer, primary_key=True),
+        Column('ref_num', Integer, primary_key=True),
+        Column('description', String(60), nullable=False)
+    )
+
+And then a table ``invoice_item`` with a composite foreign key referencing
+``invoice``::
+
+    invoice_item = Table('invoice_item', metadata,
+        Column('item_id', Integer, primary_key=True),
+        Column('item_name', String(60), nullable=False),
+        Column('invoice_id', Integer, nullable=False),
+        Column('ref_num', Integer, nullable=False),
+        ForeignKeyConstraint(['invoice_id', 'ref_num'], ['invoice.invoice_id', 'invoice.ref_num'])
+    )
+
+It's important to note that the
+:class:`~sqlalchemy.schema.ForeignKeyConstraint` is the only way to define a
+composite foreign key. While we could also have placed individual
+:class:`~sqlalchemy.schema.ForeignKey` objects on both the
+``invoice_item.invoice_id`` and ``invoice_item.ref_num`` columns, SQLAlchemy
+would not be aware that these two values should be paired together - it would
+be two individual foreign key constraints instead of a single composite
+foreign key referencing two columns.
+
+.. _use_alter:
+
+Creating/Dropping Foreign Key Constraints via ALTER
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In all the above examples, the :class:`~sqlalchemy.schema.ForeignKey` object
+causes the "REFERENCES" keyword to be added inline to a column definition
+within a "CREATE TABLE" statement when
+:func:`~sqlalchemy.schema.MetaData.create_all` is issued, and
+:class:`~sqlalchemy.schema.ForeignKeyConstraint` invokes the "CONSTRAINT"
+keyword inline with "CREATE TABLE". There are some cases where this is
+undesireable, particularly when two tables reference each other mutually, each
+with a foreign key referencing the other. In such a situation at least one of
+the foreign key constraints must be generated after both tables have been
+built. To support such a scheme, :class:`~sqlalchemy.schema.ForeignKey` and
+:class:`~sqlalchemy.schema.ForeignKeyConstraint` offer the flag
+``use_alter=True``. When using this flag, the constraint will be generated
+using a definition similar to "ALTER TABLE <tablename> ADD CONSTRAINT <name>
+...". Since a name is required, the ``name`` attribute must also be specified.
+For example::
+
+    node = Table('node', meta,
+        Column('node_id', Integer, primary_key=True),
+        Column('primary_element', Integer,
+            ForeignKey('element.element_id', use_alter=True, name='fk_node_element_id')
+        )
+    )
+
+    element = Table('element', meta,
+        Column('element_id', Integer, primary_key=True),
+        Column('parent_node_id', Integer),
+        ForeignKeyConstraint(
+            ['parent_node_id'],
+            ['node.node_id'],
+            use_alter=True,
+            name='fk_element_parent_node_id'
+        )
+    )
+
+ON UPDATE and ON DELETE
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Most databases support *cascading* of foreign key values, that is the when a
+parent row is updated the new value is placed in child rows, or when the
+parent row is deleted all corresponding child rows are set to null or deleted.
+In data definition language these are specified using phrases like "ON UPDATE
+CASCADE", "ON DELETE CASCADE", and "ON DELETE SET NULL", corresponding to
+foreign key constraints. The phrase after "ON UPDATE" or "ON DELETE" may also
+other allow other phrases that are specific to the database in use. The
+:class:`~sqlalchemy.schema.ForeignKey` and
+:class:`~sqlalchemy.schema.ForeignKeyConstraint` objects support the
+generation of this clause via the ``onupdate`` and ``ondelete`` keyword
+arguments. The value is any string which will be output after the appropriate
+"ON UPDATE" or "ON DELETE" phrase::
+
+    child = Table('child', meta,
+        Column('id', Integer,
+                ForeignKey('parent.id', onupdate="CASCADE", ondelete="CASCADE"),
+                primary_key=True
+        )
+    )
+
+    composite = Table('composite', meta,
+        Column('id', Integer, primary_key=True),
+        Column('rev_id', Integer),
+        Column('note_id', Integer),
+        ForeignKeyConstraint(
+                    ['rev_id', 'note_id'],
+                    ['revisions.id', 'revisions.note_id'],
+                    onupdate="CASCADE", ondelete="SET NULL"
+        )
+    )
+
+Note that these clauses are not supported on SQLite, and require ``InnoDB``
+tables when used with MySQL. They may also not be supported on other
+databases.
+
+
+UNIQUE Constraint
+-----------------
+
+Unique constraints can be created anonymously on a single column using the
+``unique`` keyword on :class:`~sqlalchemy.schema.Column`. Explicitly named
+unique constraints and/or those with multiple columns are created via the
+:class:`~sqlalchemy.schema.UniqueConstraint` table-level construct.
+
+.. sourcecode:: python+sql
+
+    meta = MetaData()
+    mytable = Table('mytable', meta,
+
+        # per-column anonymous unique constraint
+        Column('col1', Integer, unique=True),
+
+        Column('col2', Integer),
+        Column('col3', Integer),
+
+        # explicit/composite unique constraint.  'name' is optional.
+        UniqueConstraint('col2', 'col3', name='uix_1')
+        )
+
+CHECK Constraint
+----------------
+
+Check constraints can be named or unnamed and can be created at the Column or
+Table level, using the :class:`~sqlalchemy.schema.CheckConstraint` construct.
+The text of the check constraint is passed directly through to the database,
+so there is limited "database independent" behavior. Column level check
+constraints generally should only refer to the column to which they are
+placed, while table level constraints can refer to any columns in the table.
+
+Note that some databases do not actively support check constraints such as
+MySQL.
+
+.. sourcecode:: python+sql
+
+    meta = MetaData()
+    mytable = Table('mytable', meta,
+
+        # per-column CHECK constraint
+        Column('col1', Integer, CheckConstraint('col1>5')),
+
+        Column('col2', Integer),
+        Column('col3', Integer),
+
+        # table level CHECK constraint.  'name' is optional.
+        CheckConstraint('col2 > col3 + 5', name='check1')
+        )
+
+    {sql}mytable.create(engine)
+    CREATE TABLE mytable (
+        col1 INTEGER  CHECK (col1>5),
+        col2 INTEGER,
+        col3 INTEGER,
+        CONSTRAINT check1  CHECK (col2 > col3 + 5)
+    ){stop}
+
+Setting up Constraints when using the Declarative ORM Extension
+----------------------------------------------------------------
+
+The :class:`.Table` is the SQLAlchemy Core construct that allows one to define
+table metadata, which among other things can be used by the SQLAlchemy ORM
+as a target to map a class.  The :ref:`Declarative <declarative_toplevel>`
+extension allows the :class:`.Table` object to be created automatically, given
+the contents of the table primarily as a mapping of :class:`.Column` objects.
+
+To apply table-level constraint objects such as :class:`.ForeignKeyConstraint`
+to a table defined using Declarative, use the ``__table_args__`` attribute,
+described at :ref:`declarative_table_args`.
+
+Constraints API
+---------------
+.. autoclass:: Constraint
+
+
+.. autoclass:: CheckConstraint
+
+
+.. autoclass:: ColumnCollectionConstraint
+
+
+.. autoclass:: ForeignKey
+    :members:
+
+
+.. autoclass:: ForeignKeyConstraint
+    :members:
+
+
+.. autoclass:: PrimaryKeyConstraint
+
+
+.. autoclass:: UniqueConstraint
+
+
+.. _schema_indexes:
+
+Indexes
+-------
+
+Indexes can be created anonymously (using an auto-generated name ``ix_<column
+label>``) for a single column using the inline ``index`` keyword on
+:class:`~sqlalchemy.schema.Column`, which also modifies the usage of
+``unique`` to apply the uniqueness to the index itself, instead of adding a
+separate UNIQUE constraint. For indexes with specific names or which encompass
+more than one column, use the :class:`~sqlalchemy.schema.Index` construct,
+which requires a name.
+
+Below we illustrate a :class:`~sqlalchemy.schema.Table` with several
+:class:`~sqlalchemy.schema.Index` objects associated. The DDL for "CREATE
+INDEX" is issued right after the create statements for the table:
+
+.. sourcecode:: python+sql
+
+    meta = MetaData()
+    mytable = Table('mytable', meta,
+        # an indexed column, with index "ix_mytable_col1"
+        Column('col1', Integer, index=True),
+
+        # a uniquely indexed column with index "ix_mytable_col2"
+        Column('col2', Integer, index=True, unique=True),
+
+        Column('col3', Integer),
+        Column('col4', Integer),
+
+        Column('col5', Integer),
+        Column('col6', Integer),
+        )
+
+    # place an index on col3, col4
+    Index('idx_col34', mytable.c.col3, mytable.c.col4)
+
+    # place a unique index on col5, col6
+    Index('myindex', mytable.c.col5, mytable.c.col6, unique=True)
+
+    {sql}mytable.create(engine)
+    CREATE TABLE mytable (
+        col1 INTEGER,
+        col2 INTEGER,
+        col3 INTEGER,
+        col4 INTEGER,
+        col5 INTEGER,
+        col6 INTEGER
+    )
+    CREATE INDEX ix_mytable_col1 ON mytable (col1)
+    CREATE UNIQUE INDEX ix_mytable_col2 ON mytable (col2)
+    CREATE UNIQUE INDEX myindex ON mytable (col5, col6)
+    CREATE INDEX idx_col34 ON mytable (col3, col4){stop}
+
+Note in the example above, the :class:`.Index` construct is created
+externally to the table which it corresponds, using :class:`.Column`
+objects directly.  :class:`.Index` also supports
+"inline" definition inside the :class:`.Table`, using string names to
+identify columns::
+
+    meta = MetaData()
+    mytable = Table('mytable', meta,
+        Column('col1', Integer),
+
+        Column('col2', Integer),
+
+        Column('col3', Integer),
+        Column('col4', Integer),
+
+        # place an index on col1, col2
+        Index('idx_col12', 'col1', 'col2'),
+
+        # place a unique index on col3, col4
+        Index('idx_col34', 'col3', 'col4', unique=True)
+    )
+
+.. versionadded:: 0.7
+    Support of "inline" definition inside the :class:`.Table`
+    for :class:`.Index`\ .
+
+The :class:`~sqlalchemy.schema.Index` object also supports its own ``create()`` method:
+
+.. sourcecode:: python+sql
+
+    i = Index('someindex', mytable.c.col5)
+    {sql}i.create(engine)
+    CREATE INDEX someindex ON mytable (col5){stop}
+
+.. _schema_indexes_functional:
+
+Functional Indexes
+~~~~~~~~~~~~~~~~~~~
+
+:class:`.Index` supports SQL and function expressions, as supported by the
+target backend.  To create an index against a column using a descending
+value, the :meth:`.ColumnElement.desc` modifier may be used::
+
+    from sqlalchemy import Index
+
+    Index('someindex', mytable.c.somecol.desc())
+
+Or with a backend that supports functional indexes such as Postgresql,
+a "case insensitive" index can be created using the ``lower()`` function::
+
+    from sqlalchemy import func, Index
+
+    Index('someindex', func.lower(mytable.c.somecol))
+
+.. versionadded:: 0.8 :class:`.Index` supports SQL expressions and functions
+   as well as plain columns.
+
+Index API
+---------
+
+.. autoclass:: Index
+    :members:
diff --git a/doc/build/core/ddl.rst b/doc/build/core/ddl.rst
new file mode 100644 (file)
index 0000000..cee6f87
--- /dev/null
@@ -0,0 +1,287 @@
+.. _metadata_ddl_toplevel:
+.. _metadata_ddl:
+.. module:: sqlalchemy.schema
+
+Customizing DDL
+===============
+
+In the preceding sections we've discussed a variety of schema constructs
+including :class:`~sqlalchemy.schema.Table`,
+:class:`~sqlalchemy.schema.ForeignKeyConstraint`,
+:class:`~sqlalchemy.schema.CheckConstraint`, and
+:class:`~sqlalchemy.schema.Sequence`. Throughout, we've relied upon the
+``create()`` and :func:`~sqlalchemy.schema.MetaData.create_all` methods of
+:class:`~sqlalchemy.schema.Table` and :class:`~sqlalchemy.schema.MetaData` in
+order to issue data definition language (DDL) for all constructs. When issued,
+a pre-determined order of operations is invoked, and DDL to create each table
+is created unconditionally including all constraints and other objects
+associated with it. For more complex scenarios where database-specific DDL is
+required, SQLAlchemy offers two techniques which can be used to add any DDL
+based on any condition, either accompanying the standard generation of tables
+or by itself.
+
+.. _schema_ddl_sequences:
+
+Controlling DDL Sequences
+-------------------------
+
+The ``sqlalchemy.schema`` package contains SQL expression constructs that
+provide DDL expressions. For example, to produce a ``CREATE TABLE`` statement:
+
+.. sourcecode:: python+sql
+
+    from sqlalchemy.schema import CreateTable
+    {sql}engine.execute(CreateTable(mytable))
+    CREATE TABLE mytable (
+        col1 INTEGER,
+        col2 INTEGER,
+        col3 INTEGER,
+        col4 INTEGER,
+        col5 INTEGER,
+        col6 INTEGER
+    ){stop}
+
+Above, the :class:`~sqlalchemy.schema.CreateTable` construct works like any
+other expression construct (such as ``select()``, ``table.insert()``, etc.). A
+full reference of available constructs is in :ref:`schema_api_ddl`.
+
+The DDL constructs all extend a common base class which provides the
+capability to be associated with an individual
+:class:`~sqlalchemy.schema.Table` or :class:`~sqlalchemy.schema.MetaData`
+object, to be invoked upon create/drop events. Consider the example of a table
+which contains a CHECK constraint:
+
+.. sourcecode:: python+sql
+
+    users = Table('users', metadata,
+                   Column('user_id', Integer, primary_key=True),
+                   Column('user_name', String(40), nullable=False),
+                   CheckConstraint('length(user_name) >= 8',name="cst_user_name_length")
+                   )
+
+    {sql}users.create(engine)
+    CREATE TABLE users (
+        user_id SERIAL NOT NULL,
+        user_name VARCHAR(40) NOT NULL,
+        PRIMARY KEY (user_id),
+        CONSTRAINT cst_user_name_length  CHECK (length(user_name) >= 8)
+    ){stop}
+
+The above table contains a column "user_name" which is subject to a CHECK
+constraint that validates that the length of the string is at least eight
+characters. When a ``create()`` is issued for this table, DDL for the
+:class:`~sqlalchemy.schema.CheckConstraint` will also be issued inline within
+the table definition.
+
+The :class:`~sqlalchemy.schema.CheckConstraint` construct can also be
+constructed externally and associated with the
+:class:`~sqlalchemy.schema.Table` afterwards::
+
+    constraint = CheckConstraint('length(user_name) >= 8',name="cst_user_name_length")
+    users.append_constraint(constraint)
+
+So far, the effect is the same. However, if we create DDL elements
+corresponding to the creation and removal of this constraint, and associate
+them with the :class:`.Table` as events, these new events
+will take over the job of issuing DDL for the constraint. Additionally, the
+constraint will be added via ALTER:
+
+.. sourcecode:: python+sql
+
+    from sqlalchemy import event
+
+    event.listen(
+        users,
+        "after_create",
+        AddConstraint(constraint)
+    )
+    event.listen(
+        users,
+        "before_drop",
+        DropConstraint(constraint)
+    )
+
+    {sql}users.create(engine)
+    CREATE TABLE users (
+        user_id SERIAL NOT NULL,
+        user_name VARCHAR(40) NOT NULL,
+        PRIMARY KEY (user_id)
+    )
+
+    ALTER TABLE users ADD CONSTRAINT cst_user_name_length  CHECK (length(user_name) >= 8){stop}
+
+    {sql}users.drop(engine)
+    ALTER TABLE users DROP CONSTRAINT cst_user_name_length
+    DROP TABLE users{stop}
+
+The real usefulness of the above becomes clearer once we illustrate the
+:meth:`.DDLElement.execute_if` method.  This method returns a modified form of
+the DDL callable which will filter on criteria before responding to a
+received event.   It accepts a parameter ``dialect``, which is the string
+name of a dialect or a tuple of such, which will limit the execution of the
+item to just those dialects.  It also accepts a ``callable_`` parameter which
+may reference a Python callable which will be invoked upon event reception,
+returning ``True`` or ``False`` indicating if the event should proceed.
+
+If our :class:`~sqlalchemy.schema.CheckConstraint` was only supported by
+Postgresql and not other databases, we could limit its usage to just that dialect::
+
+    event.listen(
+        users,
+        'after_create',
+        AddConstraint(constraint).execute_if(dialect='postgresql')
+    )
+    event.listen(
+        users,
+        'before_drop',
+        DropConstraint(constraint).execute_if(dialect='postgresql')
+    )
+
+Or to any set of dialects::
+
+    event.listen(
+        users,
+        "after_create",
+        AddConstraint(constraint).execute_if(dialect=('postgresql', 'mysql'))
+    )
+    event.listen(
+        users,
+        "before_drop",
+        DropConstraint(constraint).execute_if(dialect=('postgresql', 'mysql'))
+    )
+
+When using a callable, the callable is passed the ddl element, the
+:class:`.Table` or :class:`.MetaData`
+object whose "create" or "drop" event is in progress, and the
+:class:`.Connection` object being used for the
+operation, as well as additional information as keyword arguments. The
+callable can perform checks, such as whether or not a given item already
+exists. Below we define ``should_create()`` and ``should_drop()`` callables
+that check for the presence of our named constraint:
+
+.. sourcecode:: python+sql
+
+    def should_create(ddl, target, connection, **kw):
+        row = connection.execute("select conname from pg_constraint where conname='%s'" % ddl.element.name).scalar()
+        return not bool(row)
+
+    def should_drop(ddl, target, connection, **kw):
+        return not should_create(ddl, target, connection, **kw)
+
+    event.listen(
+        users,
+        "after_create",
+        AddConstraint(constraint).execute_if(callable_=should_create)
+    )
+    event.listen(
+        users,
+        "before_drop",
+        DropConstraint(constraint).execute_if(callable_=should_drop)
+    )
+
+    {sql}users.create(engine)
+    CREATE TABLE users (
+        user_id SERIAL NOT NULL,
+        user_name VARCHAR(40) NOT NULL,
+        PRIMARY KEY (user_id)
+    )
+
+    select conname from pg_constraint where conname='cst_user_name_length'
+    ALTER TABLE users ADD CONSTRAINT cst_user_name_length  CHECK (length(user_name) >= 8){stop}
+
+    {sql}users.drop(engine)
+    select conname from pg_constraint where conname='cst_user_name_length'
+    ALTER TABLE users DROP CONSTRAINT cst_user_name_length
+    DROP TABLE users{stop}
+
+Custom DDL
+----------
+
+Custom DDL phrases are most easily achieved using the
+:class:`~sqlalchemy.schema.DDL` construct. This construct works like all the
+other DDL elements except it accepts a string which is the text to be emitted:
+
+.. sourcecode:: python+sql
+
+    event.listen(
+        metadata,
+        "after_create",
+        DDL("ALTER TABLE users ADD CONSTRAINT "
+            "cst_user_name_length "
+            " CHECK (length(user_name) >= 8)")
+    )
+
+A more comprehensive method of creating libraries of DDL constructs is to use
+custom compilation - see :ref:`sqlalchemy.ext.compiler_toplevel` for
+details.
+
+.. _schema_api_ddl:
+
+DDL Expression Constructs API
+-----------------------------
+
+.. autoclass:: DDLElement
+    :members:
+    :undoc-members:
+     
+
+.. autoclass:: DDL
+    :members:
+    :undoc-members:
+     
+
+.. autoclass:: CreateTable
+    :members:
+    :undoc-members:
+     
+
+.. autoclass:: DropTable
+    :members:
+    :undoc-members:
+     
+
+.. autoclass:: CreateColumn
+    :members:
+    :undoc-members:
+     
+
+.. autoclass:: CreateSequence
+    :members:
+    :undoc-members:
+     
+
+.. autoclass:: DropSequence
+    :members:
+    :undoc-members:
+     
+
+.. autoclass:: CreateIndex
+    :members:
+    :undoc-members:
+     
+
+.. autoclass:: DropIndex
+    :members:
+    :undoc-members:
+     
+
+.. autoclass:: AddConstraint
+    :members:
+    :undoc-members:
+     
+
+.. autoclass:: DropConstraint
+    :members:
+    :undoc-members:
+     
+
+.. autoclass:: CreateSchema
+    :members:
+    :undoc-members:
+     
+
+.. autoclass:: DropSchema
+    :members:
+    :undoc-members:
+     
+
diff --git a/doc/build/core/defaults.rst b/doc/build/core/defaults.rst
new file mode 100644 (file)
index 0000000..54a757e
--- /dev/null
@@ -0,0 +1,344 @@
+.. _metadata_defaults_toplevel:
+.. _metadata_defaults:
+.. module:: sqlalchemy.schema
+
+Column Insert/Update Defaults
+==============================
+
+SQLAlchemy provides a very rich featureset regarding column level events which
+take place during INSERT and UPDATE statements. Options include:
+
+* Scalar values used as defaults during INSERT and UPDATE operations
+* Python functions which execute upon INSERT and UPDATE operations
+* SQL expressions which are embedded in INSERT statements (or in some cases execute beforehand)
+* SQL expressions which are embedded in UPDATE statements
+* Server side default values used during INSERT
+* Markers for server-side triggers used during UPDATE
+
+The general rule for all insert/update defaults is that they only take effect
+if no value for a particular column is passed as an ``execute()`` parameter;
+otherwise, the given value is used.
+
+Scalar Defaults
+---------------
+
+The simplest kind of default is a scalar value used as the default value of a column::
+
+    Table("mytable", meta,
+        Column("somecolumn", Integer, default=12)
+    )
+
+Above, the value "12" will be bound as the column value during an INSERT if no
+other value is supplied.
+
+A scalar value may also be associated with an UPDATE statement, though this is
+not very common (as UPDATE statements are usually looking for dynamic
+defaults)::
+
+    Table("mytable", meta,
+        Column("somecolumn", Integer, onupdate=25)
+    )
+
+
+Python-Executed Functions
+-------------------------
+
+The ``default`` and ``onupdate`` keyword arguments also accept Python
+functions. These functions are invoked at the time of insert or update if no
+other value for that column is supplied, and the value returned is used for
+the column's value. Below illustrates a crude "sequence" that assigns an
+incrementing counter to a primary key column::
+
+    # a function which counts upwards
+    i = 0
+    def mydefault():
+        global i
+        i += 1
+        return i
+
+    t = Table("mytable", meta,
+        Column('id', Integer, primary_key=True, default=mydefault),
+    )
+
+It should be noted that for real "incrementing sequence" behavior, the
+built-in capabilities of the database should normally be used, which may
+include sequence objects or other autoincrementing capabilities. For primary
+key columns, SQLAlchemy will in most cases use these capabilities
+automatically. See the API documentation for
+:class:`~sqlalchemy.schema.Column` including the ``autoincrement`` flag, as
+well as the section on :class:`~sqlalchemy.schema.Sequence` later in this
+chapter for background on standard primary key generation techniques.
+
+To illustrate onupdate, we assign the Python ``datetime`` function ``now`` to
+the ``onupdate`` attribute::
+
+    import datetime
+
+    t = Table("mytable", meta,
+        Column('id', Integer, primary_key=True),
+
+        # define 'last_updated' to be populated with datetime.now()
+        Column('last_updated', DateTime, onupdate=datetime.datetime.now),
+    )
+
+When an update statement executes and no value is passed for ``last_updated``,
+the ``datetime.datetime.now()`` Python function is executed and its return
+value used as the value for ``last_updated``. Notice that we provide ``now``
+as the function itself without calling it (i.e. there are no parenthesis
+following) - SQLAlchemy will execute the function at the time the statement
+executes.
+
+Context-Sensitive Default Functions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The Python functions used by ``default`` and ``onupdate`` may also make use of
+the current statement's context in order to determine a value. The `context`
+of a statement is an internal SQLAlchemy object which contains all information
+about the statement being executed, including its source expression, the
+parameters associated with it and the cursor. The typical use case for this
+context with regards to default generation is to have access to the other
+values being inserted or updated on the row. To access the context, provide a
+function that accepts a single ``context`` argument::
+
+    def mydefault(context):
+        return context.current_parameters['counter'] + 12
+
+    t = Table('mytable', meta,
+        Column('counter', Integer),
+        Column('counter_plus_twelve', Integer, default=mydefault, onupdate=mydefault)
+    )
+
+Above we illustrate a default function which will execute for all INSERT and
+UPDATE statements where a value for ``counter_plus_twelve`` was otherwise not
+provided, and the value will be that of whatever value is present in the
+execution for the ``counter`` column, plus the number 12.
+
+While the context object passed to the default function has many attributes,
+the ``current_parameters`` member is a special member provided only during the
+execution of a default function for the purposes of deriving defaults from its
+existing values. For a single statement that is executing many sets of bind
+parameters, the user-defined function is called for each set of parameters,
+and ``current_parameters`` will be provided with each individual parameter set
+for each execution.
+
+SQL Expressions
+---------------
+
+The "default" and "onupdate" keywords may also be passed SQL expressions,
+including select statements or direct function calls::
+
+    t = Table("mytable", meta,
+        Column('id', Integer, primary_key=True),
+
+        # define 'create_date' to default to now()
+        Column('create_date', DateTime, default=func.now()),
+
+        # define 'key' to pull its default from the 'keyvalues' table
+        Column('key', String(20), default=keyvalues.select(keyvalues.c.type='type1', limit=1)),
+
+        # define 'last_modified' to use the current_timestamp SQL function on update
+        Column('last_modified', DateTime, onupdate=func.utc_timestamp())
+        )
+
+Above, the ``create_date`` column will be populated with the result of the
+``now()`` SQL function (which, depending on backend, compiles into ``NOW()``
+or ``CURRENT_TIMESTAMP`` in most cases) during an INSERT statement, and the
+``key`` column with the result of a SELECT subquery from another table. The
+``last_modified`` column will be populated with the value of
+``UTC_TIMESTAMP()``, a function specific to MySQL, when an UPDATE statement is
+emitted for this table.
+
+Note that when using ``func`` functions, unlike when using Python `datetime`
+functions we *do* call the function, i.e. with parenthesis "()" - this is
+because what we want in this case is the return value of the function, which
+is the SQL expression construct that will be rendered into the INSERT or
+UPDATE statement.
+
+The above SQL functions are usually executed "inline" with the INSERT or
+UPDATE statement being executed, meaning, a single statement is executed which
+embeds the given expressions or subqueries within the VALUES or SET clause of
+the statement. Although in some cases, the function is "pre-executed" in a
+SELECT statement of its own beforehand. This happens when all of the following
+is true:
+
+* the column is a primary key column
+* the database dialect does not support a usable ``cursor.lastrowid`` accessor
+  (or equivalent); this currently includes PostgreSQL, Oracle, and Firebird, as
+  well as some MySQL dialects.
+* the dialect does not support the "RETURNING" clause or similar, or the
+  ``implicit_returning`` flag is set to ``False`` for the dialect. Dialects
+  which support RETURNING currently include Postgresql, Oracle, Firebird, and
+  MS-SQL.
+* the statement is a single execution, i.e. only supplies one set of
+  parameters and doesn't use "executemany" behavior
+* the ``inline=True`` flag is not set on the
+  :class:`~sqlalchemy.sql.expression.Insert()` or
+  :class:`~sqlalchemy.sql.expression.Update()` construct, and the statement has
+  not defined an explicit `returning()` clause.
+
+Whether or not the default generation clause "pre-executes" is not something
+that normally needs to be considered, unless it is being addressed for
+performance reasons.
+
+When the statement is executed with a single set of parameters (that is, it is
+not an "executemany" style execution), the returned
+:class:`~sqlalchemy.engine.ResultProxy` will contain a collection
+accessible via ``result.postfetch_cols()`` which contains a list of all
+:class:`~sqlalchemy.schema.Column` objects which had an inline-executed
+default. Similarly, all parameters which were bound to the statement,
+including all Python and SQL expressions which were pre-executed, are present
+in the ``last_inserted_params()`` or ``last_updated_params()`` collections on
+:class:`~sqlalchemy.engine.ResultProxy`. The ``inserted_primary_key``
+collection contains a list of primary key values for the row inserted (a list
+so that single-column and composite-column primary keys are represented in the
+same format).
+
+Server Side Defaults
+--------------------
+
+A variant on the SQL expression default is the ``server_default``, which gets
+placed in the CREATE TABLE statement during a ``create()`` operation:
+
+.. sourcecode:: python+sql
+
+    t = Table('test', meta,
+        Column('abc', String(20), server_default='abc'),
+        Column('created_at', DateTime, server_default=text("sysdate"))
+    )
+
+A create call for the above table will produce::
+
+    CREATE TABLE test (
+        abc varchar(20) default 'abc',
+        created_at datetime default sysdate
+    )
+
+The behavior of ``server_default`` is similar to that of a regular SQL
+default; if it's placed on a primary key column for a database which doesn't
+have a way to "postfetch" the ID, and the statement is not "inlined", the SQL
+expression is pre-executed; otherwise, SQLAlchemy lets the default fire off on
+the database side normally.
+
+.. _triggered_columns:
+
+Triggered Columns
+------------------
+
+Columns with values set by a database trigger or other external process may be
+called out using :class:`.FetchedValue` as a marker::
+
+    t = Table('test', meta,
+        Column('abc', String(20), server_default=FetchedValue()),
+        Column('def', String(20), server_onupdate=FetchedValue())
+    )
+
+.. versionchanged:: 0.8.0b2,0.7.10
+    The ``for_update`` argument on :class:`.FetchedValue` is set automatically
+    when specified as the ``server_onupdate`` argument.  If using an older version,
+    specify the onupdate above as ``server_onupdate=FetchedValue(for_update=True)``.
+
+These markers do not emit a "default" clause when the table is created,
+however they do set the same internal flags as a static ``server_default``
+clause, providing hints to higher-level tools that a "post-fetch" of these
+rows should be performed after an insert or update.
+
+.. note::
+
+    It's generally not appropriate to use :class:`.FetchedValue` in
+    conjunction with a primary key column, particularly when using the
+    ORM or any other scenario where the :attr:`.ResultProxy.inserted_primary_key`
+    attribute is required.  This is becaue the "post-fetch" operation requires
+    that the primary key value already be available, so that the
+    row can be selected on its primary key.
+
+    For a server-generated primary key value, all databases provide special
+    accessors or other techniques in order to acquire the "last inserted
+    primary key" column of a table.  These mechanisms aren't affected by the presence
+    of :class:`.FetchedValue`.  For special situations where triggers are
+    used to generate primary key values, and the database in use does not
+    support the ``RETURNING`` clause, it may be necessary to forego the usage
+    of the trigger and instead apply the SQL expression or function as a
+    "pre execute" expression::
+
+        t = Table('test', meta,
+                Column('abc', MyType, default=func.generate_new_value(), primary_key=True)
+        )
+
+    Where above, when :meth:`.Table.insert` is used,
+    the ``func.generate_new_value()`` expression will be pre-executed
+    in the context of a scalar ``SELECT`` statement, and the new value will
+    be applied to the subsequent ``INSERT``, while at the same time being
+    made available to the :attr:`.ResultProxy.inserted_primary_key`
+    attribute.
+
+
+Defining Sequences
+-------------------
+
+SQLAlchemy represents database sequences using the
+:class:`~sqlalchemy.schema.Sequence` object, which is considered to be a
+special case of "column default". It only has an effect on databases which
+have explicit support for sequences, which currently includes Postgresql,
+Oracle, and Firebird. The :class:`~sqlalchemy.schema.Sequence` object is
+otherwise ignored.
+
+The :class:`~sqlalchemy.schema.Sequence` may be placed on any column as a
+"default" generator to be used during INSERT operations, and can also be
+configured to fire off during UPDATE operations if desired. It is most
+commonly used in conjunction with a single integer primary key column::
+
+    table = Table("cartitems", meta,
+        Column("cart_id", Integer, Sequence('cart_id_seq'), primary_key=True),
+        Column("description", String(40)),
+        Column("createdate", DateTime())
+    )
+
+Where above, the table "cartitems" is associated with a sequence named
+"cart_id_seq". When INSERT statements take place for "cartitems", and no value
+is passed for the "cart_id" column, the "cart_id_seq" sequence will be used to
+generate a value.
+
+When the :class:`~sqlalchemy.schema.Sequence` is associated with a table,
+CREATE and DROP statements issued for that table will also issue CREATE/DROP
+for the sequence object as well, thus "bundling" the sequence object with its
+parent table.
+
+The :class:`~sqlalchemy.schema.Sequence` object also implements special
+functionality to accommodate Postgresql's SERIAL datatype. The SERIAL type in
+PG automatically generates a sequence that is used implicitly during inserts.
+This means that if a :class:`~sqlalchemy.schema.Table` object defines a
+:class:`~sqlalchemy.schema.Sequence` on its primary key column so that it
+works with Oracle and Firebird, the :class:`~sqlalchemy.schema.Sequence` would
+get in the way of the "implicit" sequence that PG would normally use. For this
+use case, add the flag ``optional=True`` to the
+:class:`~sqlalchemy.schema.Sequence` object - this indicates that the
+:class:`~sqlalchemy.schema.Sequence` should only be used if the database
+provides no other option for generating primary key identifiers.
+
+The :class:`~sqlalchemy.schema.Sequence` object also has the ability to be
+executed standalone like a SQL expression, which has the effect of calling its
+"next value" function::
+
+    seq = Sequence('some_sequence')
+    nextid = connection.execute(seq)
+
+Default Objects API
+-------------------
+
+.. autoclass:: ColumnDefault
+
+
+.. autoclass:: DefaultClause
+
+
+.. autoclass:: DefaultGenerator
+
+
+.. autoclass:: FetchedValue
+
+
+.. autoclass:: PassiveDefault
+
+
+.. autoclass:: Sequence
+    :members:
diff --git a/doc/build/core/dml.rst b/doc/build/core/dml.rst
new file mode 100644 (file)
index 0000000..d2901c2
--- /dev/null
@@ -0,0 +1,38 @@
+Insert, Updates, Deletes
+========================
+
+INSERT, UPDATE and DELETE statements build on a hierarchy starting
+with :class:`.UpdateBase`.   The :class:`.Insert` and :class:`.Update`
+constructs build on the intermediary :class:`.ValuesBase`.
+
+.. module:: sqlalchemy.sql.expression
+
+.. autofunction:: delete
+
+.. autofunction:: insert
+
+.. autofunction:: update
+
+
+.. autoclass:: Delete
+   :members:
+   :inherited-members:
+
+.. autoclass:: Insert
+   :members:
+   :inherited-members:
+
+.. autoclass:: Update
+  :members:
+  :inherited-members:
+
+
+.. autoclass:: UpdateBase
+  :members:
+
+
+.. autoclass:: ValuesBase
+    :members:
+
+
+
index f7d384ad96e775f37aea758beeaec71698c5878d..30270f8b02385c2a12429010c5ee000a00762eb7 100644 (file)
@@ -2,5 +2,4 @@ Core Exceptions
 ===============
 
 .. automodule:: sqlalchemy.exc
-    :show-inheritance:
     :members:
\ No newline at end of file
index b17145c53bac68b1ae9e1674947f3ffb83d73bd0..99bb988811a72f221ee0e38146c496926a8dcff1 100644 (file)
@@ -8,249 +8,13 @@ SQL Statements and Expressions API
 This section presents the API reference for the SQL Expression Language.  For a full introduction to its usage,
 see :ref:`sqlexpression_toplevel`.
 
-Functions
----------
 
-The expression package uses functions to construct SQL expressions.  The return value of each function is an object instance which is a subclass of :class:`~sqlalchemy.sql.expression.ClauseElement`.
-
-.. autofunction:: alias
-
-.. autofunction:: and_
-
-.. autofunction:: asc
-
-.. autofunction:: between
-
-.. autofunction:: bindparam
-
-.. autofunction:: case
-
-.. autofunction:: cast
-
-.. autofunction:: sqlalchemy.sql.expression.column
-
-.. autofunction:: collate
-
-.. autofunction:: delete
-
-.. autofunction:: desc
-
-.. autofunction:: distinct
-
-.. autofunction:: except_
-
-.. autofunction:: except_all
-
-.. autofunction:: exists
-
-.. autofunction:: extract
-
-.. autofunction:: false
-
-.. autodata:: func
-
-.. autofunction:: insert
-
-.. autofunction:: intersect
-
-.. autofunction:: intersect_all
-
-.. autofunction:: join
-
-.. autofunction:: label
-
-.. autofunction:: literal
-
-.. autofunction:: literal_column
-
-.. autofunction:: not_
-
-.. autofunction:: null
-
-.. autofunction:: nullsfirst
-
-.. autofunction:: nullslast
-
-.. autofunction:: or_
-
-.. autofunction:: outparam
-
-.. autofunction:: outerjoin
-
-.. autofunction:: over
-
-.. autofunction:: select
-
-.. autofunction:: subquery
-
-.. autofunction:: sqlalchemy.sql.expression.table
-
-.. autofunction:: text
-
-.. autofunction:: true
-
-.. autofunction:: tuple_
-
-.. autofunction:: type_coerce
-
-.. autofunction:: union
-
-.. autofunction:: union_all
-
-.. autofunction:: update
-
-Classes
--------
-
-.. autoclass:: Alias
-   :members:
-   :show-inheritance:
-   :inherited-members:
-
-.. autoclass:: BinaryExpression
-   :members:
-   :show-inheritance:
-   :inherited-members:
-
-.. autoclass:: BindParameter
-   :members:
-   :show-inheritance:
-   :inherited-members:
-
-.. autoclass:: ClauseElement
-   :members:
-   :show-inheritance:
-
-.. autoclass:: ClauseList
-   :members:
-   :show-inheritance:
-
-.. autoclass:: ColumnClause
-   :members:
-   :show-inheritance:
-   :inherited-members:
-
-.. autoclass:: ColumnCollection
-   :members:
-   :show-inheritance:
-
-.. autoclass:: ColumnElement
-   :members:
-   :show-inheritance:
-   :inherited-members:
-
-.. autoclass:: sqlalchemy.sql.operators.ColumnOperators
-   :members:
-   :special-members:
-   :inherited-members:
-   :show-inheritance:
-
-
-.. autoclass:: CompoundSelect
-   :members:
-   :show-inheritance:
-   :inherited-members:
-
-.. autoclass:: sqlalchemy.sql.operators.custom_op
-   :members:
-
-.. autoclass:: CTE
-   :members:
-   :show-inheritance:
-   :inherited-members:
-
-.. autoclass:: Delete
-   :members:
-   :show-inheritance:
-   :inherited-members:
-
-.. autoclass:: Executable
-   :members:
-   :show-inheritance:
-
-.. autoclass:: FunctionElement
-   :members:
-   :show-inheritance:
-   :inherited-members:
-
-.. autoclass:: Function
-   :members:
-   :show-inheritance:
-   :inherited-members:
-
-.. autoclass:: FromClause
-   :members:
-   :show-inheritance:
-
-.. autoclass:: Insert
-   :members:
-   :show-inheritance:
-   :inherited-members:
-
-.. autoclass:: Join
-   :members:
-   :show-inheritance:
-   :inherited-members:
-
-.. autoclass:: sqlalchemy.sql.operators.Operators
-   :members:
-   :special-members:
-
-.. autoclass:: Select
-   :members:
-   :show-inheritance:
-   :inherited-members:
-
-.. autoclass:: Selectable
-   :members:
-   :show-inheritance:
-
-.. autoclass:: SelectBase
-   :members:
-   :show-inheritance:
-
-.. autoclass:: TableClause
-   :members:
-   :show-inheritance:
-   :inherited-members:
-
-.. autoclass:: UnaryExpression
-   :members:
-   :show-inheritance:
-
-.. autoclass:: Update
-  :members:
-  :inherited-members:
-  :show-inheritance:
-
-.. autoclass:: UpdateBase
-  :members:
-  :show-inheritance:
-
-.. autoclass:: ValuesBase
-    :members:
-    :show-inheritance:
-
-.. _generic_functions:
-
-Generic Functions
------------------
-
-SQL functions which are known to SQLAlchemy with regards to database-specific
-rendering, return types and argument behavior. Generic functions are invoked
-like all SQL functions, using the :attr:`func` attribute::
-
-    select([func.count()]).select_from(sometable)
-
-Note that any name not known to :attr:`func` generates the function name as is
-- there is no restriction on what SQL functions can be called, known or
-unknown to SQLAlchemy, built-in or user defined. The section here only
-describes those functions where SQLAlchemy already knows what argument and
-return types are in use.
-
-.. automodule:: sqlalchemy.sql.functions
-   :members:
-   :undoc-members:
-   :show-inheritance:
+.. toctree::
+    :maxdepth: 1
 
+    sqlelement
+    selectable
+    dml
+    functions
+    types
 
diff --git a/doc/build/core/functions.rst b/doc/build/core/functions.rst
new file mode 100644 (file)
index 0000000..d284d12
--- /dev/null
@@ -0,0 +1,27 @@
+.. _functions_toplevel:
+.. _generic_functions:
+
+=========================
+SQL and Generic Functions
+=========================
+
+.. module:: sqlalchemy.sql.expression
+
+SQL functions which are known to SQLAlchemy with regards to database-specific
+rendering, return types and argument behavior. Generic functions are invoked
+like all SQL functions, using the :attr:`func` attribute::
+
+    select([func.count()]).select_from(sometable)
+
+Note that any name not known to :attr:`func` generates the function name as is
+- there is no restriction on what SQL functions can be called, known or
+unknown to SQLAlchemy, built-in or user defined. The section here only
+describes those functions where SQLAlchemy already knows what argument and
+return types are in use.
+
+.. automodule:: sqlalchemy.sql.functions
+   :members:
+   :undoc-members:
+    
+
+
index 079a4b97acfde8286be322336560567c584c80a6..210f284123d1a4789f0a84962645c9a6e7d2c249 100644 (file)
@@ -13,11 +13,10 @@ Language provides a schema-centric usage paradigm.
 
     tutorial
     expression_api
+    schema
     engines
     connections
     pooling
-    schema
-    types
     event
     events
     compiler
index 64dc34183eb4a65b3bacef6e04734df6c7f2491c..1a85e9e6c62fee74502edcd5dcd7c8793914b3d8 100644 (file)
@@ -12,12 +12,10 @@ Some key internal constructs are listed here.
 
 .. autoclass:: sqlalchemy.sql.compiler.DDLCompiler
     :members:
-    :show-inheritance:
     :inherited-members:
 
 .. autoclass:: sqlalchemy.engine.default.DefaultDialect
     :members:
-    :show-inheritance:
     :inherited-members:
 
 .. autoclass:: sqlalchemy.engine.interfaces.Dialect
@@ -25,17 +23,17 @@ Some key internal constructs are listed here.
 
 .. autoclass:: sqlalchemy.engine.default.DefaultExecutionContext
     :members:
-    :show-inheritance:
+
 
 .. autoclass:: sqlalchemy.engine.interfaces.ExecutionContext
     :members:
-    :show-inheritance:
+
 
 .. autoclass:: sqlalchemy.sql.compiler.IdentifierPreparer
     :members:
-    :show-inheritance:
+
 
 .. autoclass:: sqlalchemy.sql.compiler.SQLCompiler
     :members:
-    :show-inheritance:
+
 
diff --git a/doc/build/core/metadata.rst b/doc/build/core/metadata.rst
new file mode 100644 (file)
index 0000000..7b9c500
--- /dev/null
@@ -0,0 +1,325 @@
+.. _metadata_toplevel:
+.. _metadata_describing_toplevel:
+.. _metadata_describing:
+.. module:: sqlalchemy.schema
+
+==================================
+Describing Databases with MetaData
+==================================
+
+This section discusses the fundamental :class:`.Table`, :class:`.Column`
+and :class:`.MetaData` objects.
+
+A collection of metadata entities is stored in an object aptly named
+:class:`~sqlalchemy.schema.MetaData`::
+
+    from sqlalchemy import *
+
+    metadata = MetaData()
+
+:class:`~sqlalchemy.schema.MetaData` is a container object that keeps together
+many different features of a database (or multiple databases) being described.
+
+To represent a table, use the :class:`~sqlalchemy.schema.Table` class. Its two
+primary arguments are the table name, then the
+:class:`~sqlalchemy.schema.MetaData` object which it will be associated with.
+The remaining positional arguments are mostly
+:class:`~sqlalchemy.schema.Column` objects describing each column::
+
+    user = Table('user', metadata,
+        Column('user_id', Integer, primary_key = True),
+        Column('user_name', String(16), nullable = False),
+        Column('email_address', String(60)),
+        Column('password', String(20), nullable = False)
+    )
+
+Above, a table called ``user`` is described, which contains four columns. The
+primary key of the table consists of the ``user_id`` column. Multiple columns
+may be assigned the ``primary_key=True`` flag which denotes a multi-column
+primary key, known as a *composite* primary key.
+
+Note also that each column describes its datatype using objects corresponding
+to genericized types, such as :class:`~sqlalchemy.types.Integer` and
+:class:`~sqlalchemy.types.String`. SQLAlchemy features dozens of types of
+varying levels of specificity as well as the ability to create custom types.
+Documentation on the type system can be found at :ref:`types`.
+
+Accessing Tables and Columns
+----------------------------
+
+The :class:`~sqlalchemy.schema.MetaData` object contains all of the schema
+constructs we've associated with it. It supports a few methods of accessing
+these table objects, such as the ``sorted_tables`` accessor which returns a
+list of each :class:`~sqlalchemy.schema.Table` object in order of foreign key
+dependency (that is, each table is preceded by all tables which it
+references)::
+
+    >>> for t in metadata.sorted_tables:
+    ...    print t.name
+    user
+    user_preference
+    invoice
+    invoice_item
+
+In most cases, individual :class:`~sqlalchemy.schema.Table` objects have been
+explicitly declared, and these objects are typically accessed directly as
+module-level variables in an application. Once a
+:class:`~sqlalchemy.schema.Table` has been defined, it has a full set of
+accessors which allow inspection of its properties. Given the following
+:class:`~sqlalchemy.schema.Table` definition::
+
+    employees = Table('employees', metadata,
+        Column('employee_id', Integer, primary_key=True),
+        Column('employee_name', String(60), nullable=False),
+        Column('employee_dept', Integer, ForeignKey("departments.department_id"))
+    )
+
+Note the :class:`~sqlalchemy.schema.ForeignKey` object used in this table -
+this construct defines a reference to a remote table, and is fully described
+in :ref:`metadata_foreignkeys`. Methods of accessing information about this
+table include::
+
+    # access the column "EMPLOYEE_ID":
+    employees.columns.employee_id
+
+    # or just
+    employees.c.employee_id
+
+    # via string
+    employees.c['employee_id']
+
+    # iterate through all columns
+    for c in employees.c:
+        print c
+
+    # get the table's primary key columns
+    for primary_key in employees.primary_key:
+        print primary_key
+
+    # get the table's foreign key objects:
+    for fkey in employees.foreign_keys:
+        print fkey
+
+    # access the table's MetaData:
+    employees.metadata
+
+    # access the table's bound Engine or Connection, if its MetaData is bound:
+    employees.bind
+
+    # access a column's name, type, nullable, primary key, foreign key
+    employees.c.employee_id.name
+    employees.c.employee_id.type
+    employees.c.employee_id.nullable
+    employees.c.employee_id.primary_key
+    employees.c.employee_dept.foreign_keys
+
+    # get the "key" of a column, which defaults to its name, but can
+    # be any user-defined string:
+    employees.c.employee_name.key
+
+    # access a column's table:
+    employees.c.employee_id.table is employees
+
+    # get the table related by a foreign key
+    list(employees.c.employee_dept.foreign_keys)[0].column.table
+
+Creating and Dropping Database Tables
+-------------------------------------
+
+Once you've defined some :class:`~sqlalchemy.schema.Table` objects, assuming
+you're working with a brand new database one thing you might want to do is
+issue CREATE statements for those tables and their related constructs (as an
+aside, it's also quite possible that you *don't* want to do this, if you
+already have some preferred methodology such as tools included with your
+database or an existing scripting system - if that's the case, feel free to
+skip this section - SQLAlchemy has no requirement that it be used to create
+your tables).
+
+The usual way to issue CREATE is to use
+:func:`~sqlalchemy.schema.MetaData.create_all` on the
+:class:`~sqlalchemy.schema.MetaData` object. This method will issue queries
+that first check for the existence of each individual table, and if not found
+will issue the CREATE statements:
+
+    .. sourcecode:: python+sql
+
+        engine = create_engine('sqlite:///:memory:')
+
+        metadata = MetaData()
+
+        user = Table('user', metadata,
+            Column('user_id', Integer, primary_key = True),
+            Column('user_name', String(16), nullable = False),
+            Column('email_address', String(60), key='email'),
+            Column('password', String(20), nullable = False)
+        )
+
+        user_prefs = Table('user_prefs', metadata,
+            Column('pref_id', Integer, primary_key=True),
+            Column('user_id', Integer, ForeignKey("user.user_id"), nullable=False),
+            Column('pref_name', String(40), nullable=False),
+            Column('pref_value', String(100))
+        )
+
+        {sql}metadata.create_all(engine)
+        PRAGMA table_info(user){}
+        CREATE TABLE user(
+                user_id INTEGER NOT NULL PRIMARY KEY,
+                user_name VARCHAR(16) NOT NULL,
+                email_address VARCHAR(60),
+                password VARCHAR(20) NOT NULL
+        )
+        PRAGMA table_info(user_prefs){}
+        CREATE TABLE user_prefs(
+                pref_id INTEGER NOT NULL PRIMARY KEY,
+                user_id INTEGER NOT NULL REFERENCES user(user_id),
+                pref_name VARCHAR(40) NOT NULL,
+                pref_value VARCHAR(100)
+        )
+
+:func:`~sqlalchemy.schema.MetaData.create_all` creates foreign key constraints
+between tables usually inline with the table definition itself, and for this
+reason it also generates the tables in order of their dependency. There are
+options to change this behavior such that ``ALTER TABLE`` is used instead.
+
+Dropping all tables is similarly achieved using the
+:func:`~sqlalchemy.schema.MetaData.drop_all` method. This method does the
+exact opposite of :func:`~sqlalchemy.schema.MetaData.create_all` - the
+presence of each table is checked first, and tables are dropped in reverse
+order of dependency.
+
+Creating and dropping individual tables can be done via the ``create()`` and
+``drop()`` methods of :class:`~sqlalchemy.schema.Table`. These methods by
+default issue the CREATE or DROP regardless of the table being present:
+
+.. sourcecode:: python+sql
+
+    engine = create_engine('sqlite:///:memory:')
+
+    meta = MetaData()
+
+    employees = Table('employees', meta,
+        Column('employee_id', Integer, primary_key=True),
+        Column('employee_name', String(60), nullable=False, key='name'),
+        Column('employee_dept', Integer, ForeignKey("departments.department_id"))
+    )
+    {sql}employees.create(engine)
+    CREATE TABLE employees(
+    employee_id SERIAL NOT NULL PRIMARY KEY,
+    employee_name VARCHAR(60) NOT NULL,
+    employee_dept INTEGER REFERENCES departments(department_id)
+    )
+    {}
+
+``drop()`` method:
+
+.. sourcecode:: python+sql
+
+    {sql}employees.drop(engine)
+    DROP TABLE employees
+    {}
+
+To enable the "check first for the table existing" logic, add the
+``checkfirst=True`` argument to ``create()`` or ``drop()``::
+
+    employees.create(engine, checkfirst=True)
+    employees.drop(engine, checkfirst=False)
+
+Altering Schemas through Migrations
+-----------------------------------
+
+While SQLAlchemy directly supports emitting CREATE and DROP statements for schema
+constructs, the ability to alter those constructs, usually via the ALTER statement
+as well as other database-specific constructs, is outside of the scope of SQLAlchemy
+itself.  While it's easy enough to emit ALTER statements and similar by hand,
+such as by passing a string to :meth:`.Connection.execute` or by using the
+:class:`.DDL` construct, it's a common practice to automate the maintenance of
+database schemas in relation to application code using schema migration tools.
+
+There are two major migration tools available for SQLAlchemy:
+
+* `Alembic <http://alembic.readthedocs.org>`_ - Written by the author of SQLAlchemy,
+  Alembic features a highly customizable environment and a minimalistic usage pattern,
+  supporting such features as transactional DDL, automatic generation of "candidate"
+  migrations, an "offline" mode which generates SQL scripts, and support for branch
+  resolution.
+* `SQLAlchemy-Migrate <http://code.google.com/p/sqlalchemy-migrate/>`_ - The original
+  migration tool for SQLAlchemy, SQLAlchemy-Migrate is widely used and continues
+  under active development.   SQLAlchemy-Migrate includes features such as
+  SQL script generation, ORM class generation, ORM model comparison, and extensive
+  support for SQLite migrations.
+
+
+Specifying the Schema Name
+---------------------------
+
+Some databases support the concept of multiple schemas. A
+:class:`~sqlalchemy.schema.Table` can reference this by specifying the
+``schema`` keyword argument::
+
+    financial_info = Table('financial_info', meta,
+        Column('id', Integer, primary_key=True),
+        Column('value', String(100), nullable=False),
+        schema='remote_banks'
+    )
+
+Within the :class:`~sqlalchemy.schema.MetaData` collection, this table will be
+identified by the combination of ``financial_info`` and ``remote_banks``. If
+another table called ``financial_info`` is referenced without the
+``remote_banks`` schema, it will refer to a different
+:class:`~sqlalchemy.schema.Table`. :class:`~sqlalchemy.schema.ForeignKey`
+objects can specify references to columns in this table using the form
+``remote_banks.financial_info.id``.
+
+The ``schema`` argument should be used for any name qualifiers required,
+including Oracle's "owner" attribute and similar. It also can accommodate a
+dotted name for longer schemes::
+
+    schema="dbo.scott"
+
+Backend-Specific Options
+------------------------
+
+:class:`~sqlalchemy.schema.Table` supports database-specific options. For
+example, MySQL has different table backend types, including "MyISAM" and
+"InnoDB". This can be expressed with :class:`~sqlalchemy.schema.Table` using
+``mysql_engine``::
+
+    addresses = Table('engine_email_addresses', meta,
+        Column('address_id', Integer, primary_key = True),
+        Column('remote_user_id', Integer, ForeignKey(users.c.user_id)),
+        Column('email_address', String(20)),
+        mysql_engine='InnoDB'
+    )
+
+Other backends may support table-level options as well - these would be
+described in the individual documentation sections for each dialect.
+
+Column, Table, MetaData API
+---------------------------
+
+.. autoclass:: Column
+    :members:
+    :inherited-members:
+    :undoc-members:
+
+
+.. autoclass:: MetaData
+    :members:
+    :undoc-members:
+
+
+.. autoclass:: SchemaItem
+    :members:
+
+.. autoclass:: Table
+    :members:
+    :inherited-members:
+    :undoc-members:
+
+
+.. autoclass:: ThreadLocalMetaData
+    :members:
+    :undoc-members:
+
+
index eb546307531bec34d95db01a23476f6d0fe3ecc6..83ec0252f2392f3ba9c2fb9835f04d249d8d2f5b 100644 (file)
@@ -293,23 +293,23 @@ API Documentation - Available Pool Implementations
    .. automethod:: recreate
 
 .. autoclass:: sqlalchemy.pool.QueuePool
-   :show-inheritance:
+
 
    .. automethod:: __init__
 
 .. autoclass:: SingletonThreadPool
-   :show-inheritance:
+
 
    .. automethod:: __init__
 
 .. autoclass:: AssertionPool
-   :show-inheritance:
+
 
 .. autoclass:: NullPool
-  :show-inheritance:
+
 
 .. autoclass:: StaticPool
-   :show-inheritance:
+
 
 
 Pooling Plain DB-API Connections
diff --git a/doc/build/core/reflection.rst b/doc/build/core/reflection.rst
new file mode 100644 (file)
index 0000000..17ff0b9
--- /dev/null
@@ -0,0 +1,132 @@
+.. _metadata_reflection_toplevel:
+.. _metadata_reflection:
+
+.. module:: sqlalchemy.schema
+
+
+Reflecting Database Objects
+===========================
+
+A :class:`~sqlalchemy.schema.Table` object can be instructed to load
+information about itself from the corresponding database schema object already
+existing within the database. This process is called *reflection*. In the
+most simple case you need only specify the table name, a :class:`~sqlalchemy.schema.MetaData`
+object, and the ``autoload=True`` flag. If the
+:class:`~sqlalchemy.schema.MetaData` is not persistently bound, also add the
+``autoload_with`` argument::
+
+    >>> messages = Table('messages', meta, autoload=True, autoload_with=engine)
+    >>> [c.name for c in messages.columns]
+    ['message_id', 'message_name', 'date']
+
+The above operation will use the given engine to query the database for
+information about the ``messages`` table, and will then generate
+:class:`~sqlalchemy.schema.Column`, :class:`~sqlalchemy.schema.ForeignKey`,
+and other objects corresponding to this information as though the
+:class:`~sqlalchemy.schema.Table` object were hand-constructed in Python.
+
+When tables are reflected, if a given table references another one via foreign
+key, a second :class:`~sqlalchemy.schema.Table` object is created within the
+:class:`~sqlalchemy.schema.MetaData` object representing the connection.
+Below, assume the table ``shopping_cart_items`` references a table named
+``shopping_carts``. Reflecting the ``shopping_cart_items`` table has the
+effect such that the ``shopping_carts`` table will also be loaded::
+
+    >>> shopping_cart_items = Table('shopping_cart_items', meta, autoload=True, autoload_with=engine)
+    >>> 'shopping_carts' in meta.tables:
+    True
+
+The :class:`~sqlalchemy.schema.MetaData` has an interesting "singleton-like"
+behavior such that if you requested both tables individually,
+:class:`~sqlalchemy.schema.MetaData` will ensure that exactly one
+:class:`~sqlalchemy.schema.Table` object is created for each distinct table
+name. The :class:`~sqlalchemy.schema.Table` constructor actually returns to
+you the already-existing :class:`~sqlalchemy.schema.Table` object if one
+already exists with the given name. Such as below, we can access the already
+generated ``shopping_carts`` table just by naming it::
+
+    shopping_carts = Table('shopping_carts', meta)
+
+Of course, it's a good idea to use ``autoload=True`` with the above table
+regardless. This is so that the table's attributes will be loaded if they have
+not been already. The autoload operation only occurs for the table if it
+hasn't already been loaded; once loaded, new calls to
+:class:`~sqlalchemy.schema.Table` with the same name will not re-issue any
+reflection queries.
+
+Overriding Reflected Columns
+-----------------------------
+
+Individual columns can be overridden with explicit values when reflecting
+tables; this is handy for specifying custom datatypes, constraints such as
+primary keys that may not be configured within the database, etc.::
+
+    >>> mytable = Table('mytable', meta,
+    ... Column('id', Integer, primary_key=True),   # override reflected 'id' to have primary key
+    ... Column('mydata', Unicode(50)),    # override reflected 'mydata' to be Unicode
+    ... autoload=True)
+
+Reflecting Views
+-----------------
+
+The reflection system can also reflect views. Basic usage is the same as that
+of a table::
+
+    my_view = Table("some_view", metadata, autoload=True)
+
+Above, ``my_view`` is a :class:`~sqlalchemy.schema.Table` object with
+:class:`~sqlalchemy.schema.Column` objects representing the names and types of
+each column within the view "some_view".
+
+Usually, it's desired to have at least a primary key constraint when
+reflecting a view, if not foreign keys as well. View reflection doesn't
+extrapolate these constraints.
+
+Use the "override" technique for this, specifying explicitly those columns
+which are part of the primary key or have foreign key constraints::
+
+    my_view = Table("some_view", metadata,
+                    Column("view_id", Integer, primary_key=True),
+                    Column("related_thing", Integer, ForeignKey("othertable.thing_id")),
+                    autoload=True
+    )
+
+Reflecting All Tables at Once
+-----------------------------
+
+The :class:`~sqlalchemy.schema.MetaData` object can also get a listing of
+tables and reflect the full set. This is achieved by using the
+:func:`~sqlalchemy.schema.MetaData.reflect` method. After calling it, all
+located tables are present within the :class:`~sqlalchemy.schema.MetaData`
+object's dictionary of tables::
+
+    meta = MetaData()
+    meta.reflect(bind=someengine)
+    users_table = meta.tables['users']
+    addresses_table = meta.tables['addresses']
+
+``metadata.reflect()`` also provides a handy way to clear or delete all the rows in a database::
+
+    meta = MetaData()
+    meta.reflect(bind=someengine)
+    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"::
+
+    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:: sqlalchemy.engine.reflection.Inspector
+    :members:
+    :undoc-members:
+     
+
index b2caf870fb1bc8f6a4fdbd5cd3e7ec58b92b1a24..aeb04be18c45deef9d140a4ecb1d8e45668c7a67 100644 (file)
@@ -1,4 +1,4 @@
-.. _metadata_toplevel:
+.. _schema_toplevel:
 
 ==========================
 Schema Definition Language
@@ -6,11 +6,8 @@ Schema Definition Language
 
 .. module:: sqlalchemy.schema
 
-
-.. _metadata_describing:
-
-Describing Databases with MetaData
-==================================
+This section references SQLAlchemy **schema metadata**, a comprehensive system of describing and inspecting
+database schemas.
 
 The core of SQLAlchemy's query and object mapping operations are supported by
 *database metadata*, which is comprised of Python objects that describe tables
@@ -35,1453 +32,14 @@ designed to be used in a *declarative* style which closely resembles that of
 real DDL. They are therefore most intuitive to those who have some background
 in creating real schema generation scripts.
 
-A collection of metadata entities is stored in an object aptly named
-:class:`~sqlalchemy.schema.MetaData`::
-
-    from sqlalchemy import *
-
-    metadata = MetaData()
-
-:class:`~sqlalchemy.schema.MetaData` is a container object that keeps together
-many different features of a database (or multiple databases) being described.
-
-To represent a table, use the :class:`~sqlalchemy.schema.Table` class. Its two
-primary arguments are the table name, then the
-:class:`~sqlalchemy.schema.MetaData` object which it will be associated with.
-The remaining positional arguments are mostly
-:class:`~sqlalchemy.schema.Column` objects describing each column::
-
-    user = Table('user', metadata,
-        Column('user_id', Integer, primary_key = True),
-        Column('user_name', String(16), nullable = False),
-        Column('email_address', String(60)),
-        Column('password', String(20), nullable = False)
-    )
-
-Above, a table called ``user`` is described, which contains four columns. The
-primary key of the table consists of the ``user_id`` column. Multiple columns
-may be assigned the ``primary_key=True`` flag which denotes a multi-column
-primary key, known as a *composite* primary key.
-
-Note also that each column describes its datatype using objects corresponding
-to genericized types, such as :class:`~sqlalchemy.types.Integer` and
-:class:`~sqlalchemy.types.String`. SQLAlchemy features dozens of types of
-varying levels of specificity as well as the ability to create custom types.
-Documentation on the type system can be found at :ref:`types`.
-
-Accessing Tables and Columns
-----------------------------
-
-The :class:`~sqlalchemy.schema.MetaData` object contains all of the schema
-constructs we've associated with it. It supports a few methods of accessing
-these table objects, such as the ``sorted_tables`` accessor which returns a
-list of each :class:`~sqlalchemy.schema.Table` object in order of foreign key
-dependency (that is, each table is preceded by all tables which it
-references)::
-
-    >>> for t in metadata.sorted_tables:
-    ...    print t.name
-    user
-    user_preference
-    invoice
-    invoice_item
-
-In most cases, individual :class:`~sqlalchemy.schema.Table` objects have been
-explicitly declared, and these objects are typically accessed directly as
-module-level variables in an application. Once a
-:class:`~sqlalchemy.schema.Table` has been defined, it has a full set of
-accessors which allow inspection of its properties. Given the following
-:class:`~sqlalchemy.schema.Table` definition::
-
-    employees = Table('employees', metadata,
-        Column('employee_id', Integer, primary_key=True),
-        Column('employee_name', String(60), nullable=False),
-        Column('employee_dept', Integer, ForeignKey("departments.department_id"))
-    )
-
-Note the :class:`~sqlalchemy.schema.ForeignKey` object used in this table -
-this construct defines a reference to a remote table, and is fully described
-in :ref:`metadata_foreignkeys`. Methods of accessing information about this
-table include::
-
-    # access the column "EMPLOYEE_ID":
-    employees.columns.employee_id
-
-    # or just
-    employees.c.employee_id
-
-    # via string
-    employees.c['employee_id']
-
-    # iterate through all columns
-    for c in employees.c:
-        print c
-
-    # get the table's primary key columns
-    for primary_key in employees.primary_key:
-        print primary_key
-
-    # get the table's foreign key objects:
-    for fkey in employees.foreign_keys:
-        print fkey
-
-    # access the table's MetaData:
-    employees.metadata
-
-    # access the table's bound Engine or Connection, if its MetaData is bound:
-    employees.bind
-
-    # access a column's name, type, nullable, primary key, foreign key
-    employees.c.employee_id.name
-    employees.c.employee_id.type
-    employees.c.employee_id.nullable
-    employees.c.employee_id.primary_key
-    employees.c.employee_dept.foreign_keys
-
-    # get the "key" of a column, which defaults to its name, but can
-    # be any user-defined string:
-    employees.c.employee_name.key
-
-    # access a column's table:
-    employees.c.employee_id.table is employees
-
-    # get the table related by a foreign key
-    list(employees.c.employee_dept.foreign_keys)[0].column.table
-
-Creating and Dropping Database Tables
--------------------------------------
-
-Once you've defined some :class:`~sqlalchemy.schema.Table` objects, assuming
-you're working with a brand new database one thing you might want to do is
-issue CREATE statements for those tables and their related constructs (as an
-aside, it's also quite possible that you *don't* want to do this, if you
-already have some preferred methodology such as tools included with your
-database or an existing scripting system - if that's the case, feel free to
-skip this section - SQLAlchemy has no requirement that it be used to create
-your tables).
-
-The usual way to issue CREATE is to use
-:func:`~sqlalchemy.schema.MetaData.create_all` on the
-:class:`~sqlalchemy.schema.MetaData` object. This method will issue queries
-that first check for the existence of each individual table, and if not found
-will issue the CREATE statements:
-
-    .. sourcecode:: python+sql
-
-        engine = create_engine('sqlite:///:memory:')
-
-        metadata = MetaData()
-
-        user = Table('user', metadata,
-            Column('user_id', Integer, primary_key = True),
-            Column('user_name', String(16), nullable = False),
-            Column('email_address', String(60), key='email'),
-            Column('password', String(20), nullable = False)
-        )
-
-        user_prefs = Table('user_prefs', metadata,
-            Column('pref_id', Integer, primary_key=True),
-            Column('user_id', Integer, ForeignKey("user.user_id"), nullable=False),
-            Column('pref_name', String(40), nullable=False),
-            Column('pref_value', String(100))
-        )
-
-        {sql}metadata.create_all(engine)
-        PRAGMA table_info(user){}
-        CREATE TABLE user(
-                user_id INTEGER NOT NULL PRIMARY KEY,
-                user_name VARCHAR(16) NOT NULL,
-                email_address VARCHAR(60),
-                password VARCHAR(20) NOT NULL
-        )
-        PRAGMA table_info(user_prefs){}
-        CREATE TABLE user_prefs(
-                pref_id INTEGER NOT NULL PRIMARY KEY,
-                user_id INTEGER NOT NULL REFERENCES user(user_id),
-                pref_name VARCHAR(40) NOT NULL,
-                pref_value VARCHAR(100)
-        )
-
-:func:`~sqlalchemy.schema.MetaData.create_all` creates foreign key constraints
-between tables usually inline with the table definition itself, and for this
-reason it also generates the tables in order of their dependency. There are
-options to change this behavior such that ``ALTER TABLE`` is used instead.
-
-Dropping all tables is similarly achieved using the
-:func:`~sqlalchemy.schema.MetaData.drop_all` method. This method does the
-exact opposite of :func:`~sqlalchemy.schema.MetaData.create_all` - the
-presence of each table is checked first, and tables are dropped in reverse
-order of dependency.
-
-Creating and dropping individual tables can be done via the ``create()`` and
-``drop()`` methods of :class:`~sqlalchemy.schema.Table`. These methods by
-default issue the CREATE or DROP regardless of the table being present:
-
-.. sourcecode:: python+sql
-
-    engine = create_engine('sqlite:///:memory:')
-
-    meta = MetaData()
-
-    employees = Table('employees', meta,
-        Column('employee_id', Integer, primary_key=True),
-        Column('employee_name', String(60), nullable=False, key='name'),
-        Column('employee_dept', Integer, ForeignKey("departments.department_id"))
-    )
-    {sql}employees.create(engine)
-    CREATE TABLE employees(
-    employee_id SERIAL NOT NULL PRIMARY KEY,
-    employee_name VARCHAR(60) NOT NULL,
-    employee_dept INTEGER REFERENCES departments(department_id)
-    )
-    {}
-
-``drop()`` method:
-
-.. sourcecode:: python+sql
-
-    {sql}employees.drop(engine)
-    DROP TABLE employees
-    {}
-
-To enable the "check first for the table existing" logic, add the
-``checkfirst=True`` argument to ``create()`` or ``drop()``::
-
-    employees.create(engine, checkfirst=True)
-    employees.drop(engine, checkfirst=False)
-
-Altering Schemas through Migrations
------------------------------------
-
-While SQLAlchemy directly supports emitting CREATE and DROP statements for schema
-constructs, the ability to alter those constructs, usually via the ALTER statement
-as well as other database-specific constructs, is outside of the scope of SQLAlchemy
-itself.  While it's easy enough to emit ALTER statements and similar by hand,
-such as by passing a string to :meth:`.Connection.execute` or by using the
-:class:`.DDL` construct, it's a common practice to automate the maintenance of
-database schemas in relation to application code using schema migration tools.
-
-There are two major migration tools available for SQLAlchemy:
-
-* `Alembic <http://alembic.readthedocs.org>`_ - Written by the author of SQLAlchemy,
-  Alembic features a highly customizable environment and a minimalistic usage pattern,
-  supporting such features as transactional DDL, automatic generation of "candidate"
-  migrations, an "offline" mode which generates SQL scripts, and support for branch
-  resolution.
-* `SQLAlchemy-Migrate <http://code.google.com/p/sqlalchemy-migrate/>`_ - The original
-  migration tool for SQLAlchemy, SQLAlchemy-Migrate is widely used and continues
-  under active development.   SQLAlchemy-Migrate includes features such as
-  SQL script generation, ORM class generation, ORM model comparison, and extensive
-  support for SQLite migrations.
-
-
-Specifying the Schema Name
----------------------------
-
-Some databases support the concept of multiple schemas. A
-:class:`~sqlalchemy.schema.Table` can reference this by specifying the
-``schema`` keyword argument::
-
-    financial_info = Table('financial_info', meta,
-        Column('id', Integer, primary_key=True),
-        Column('value', String(100), nullable=False),
-        schema='remote_banks'
-    )
-
-Within the :class:`~sqlalchemy.schema.MetaData` collection, this table will be
-identified by the combination of ``financial_info`` and ``remote_banks``. If
-another table called ``financial_info`` is referenced without the
-``remote_banks`` schema, it will refer to a different
-:class:`~sqlalchemy.schema.Table`. :class:`~sqlalchemy.schema.ForeignKey`
-objects can specify references to columns in this table using the form
-``remote_banks.financial_info.id``.
-
-The ``schema`` argument should be used for any name qualifiers required,
-including Oracle's "owner" attribute and similar. It also can accommodate a
-dotted name for longer schemes::
-
-    schema="dbo.scott"
-
-Backend-Specific Options
-------------------------
-
-:class:`~sqlalchemy.schema.Table` supports database-specific options. For
-example, MySQL has different table backend types, including "MyISAM" and
-"InnoDB". This can be expressed with :class:`~sqlalchemy.schema.Table` using
-``mysql_engine``::
-
-    addresses = Table('engine_email_addresses', meta,
-        Column('address_id', Integer, primary_key = True),
-        Column('remote_user_id', Integer, ForeignKey(users.c.user_id)),
-        Column('email_address', String(20)),
-        mysql_engine='InnoDB'
-    )
-
-Other backends may support table-level options as well - these would be
-described in the individual documentation sections for each dialect.
-
-Column, Table, MetaData API
----------------------------
-
-.. autoclass:: Column
-    :members:
-    :inherited-members:
-    :undoc-members:
-    :show-inheritance:
-
-.. autoclass:: MetaData
-    :members:
-    :undoc-members:
-    :show-inheritance:
-
-.. autoclass:: SchemaItem
-    :show-inheritance:
-    :members:
-
-.. autoclass:: Table
-    :members:
-    :inherited-members:
-    :undoc-members:
-    :show-inheritance:
-
-.. autoclass:: ThreadLocalMetaData
-    :members:
-    :undoc-members:
-    :show-inheritance:
-
-
-.. _metadata_reflection:
-
-Reflecting Database Objects
-===========================
-
-A :class:`~sqlalchemy.schema.Table` object can be instructed to load
-information about itself from the corresponding database schema object already
-existing within the database. This process is called *reflection*. In the
-most simple case you need only specify the table name, a :class:`~sqlalchemy.schema.MetaData`
-object, and the ``autoload=True`` flag. If the
-:class:`~sqlalchemy.schema.MetaData` is not persistently bound, also add the
-``autoload_with`` argument::
-
-    >>> messages = Table('messages', meta, autoload=True, autoload_with=engine)
-    >>> [c.name for c in messages.columns]
-    ['message_id', 'message_name', 'date']
-
-The above operation will use the given engine to query the database for
-information about the ``messages`` table, and will then generate
-:class:`~sqlalchemy.schema.Column`, :class:`~sqlalchemy.schema.ForeignKey`,
-and other objects corresponding to this information as though the
-:class:`~sqlalchemy.schema.Table` object were hand-constructed in Python.
-
-When tables are reflected, if a given table references another one via foreign
-key, a second :class:`~sqlalchemy.schema.Table` object is created within the
-:class:`~sqlalchemy.schema.MetaData` object representing the connection.
-Below, assume the table ``shopping_cart_items`` references a table named
-``shopping_carts``. Reflecting the ``shopping_cart_items`` table has the
-effect such that the ``shopping_carts`` table will also be loaded::
-
-    >>> shopping_cart_items = Table('shopping_cart_items', meta, autoload=True, autoload_with=engine)
-    >>> 'shopping_carts' in meta.tables:
-    True
-
-The :class:`~sqlalchemy.schema.MetaData` has an interesting "singleton-like"
-behavior such that if you requested both tables individually,
-:class:`~sqlalchemy.schema.MetaData` will ensure that exactly one
-:class:`~sqlalchemy.schema.Table` object is created for each distinct table
-name. The :class:`~sqlalchemy.schema.Table` constructor actually returns to
-you the already-existing :class:`~sqlalchemy.schema.Table` object if one
-already exists with the given name. Such as below, we can access the already
-generated ``shopping_carts`` table just by naming it::
-
-    shopping_carts = Table('shopping_carts', meta)
-
-Of course, it's a good idea to use ``autoload=True`` with the above table
-regardless. This is so that the table's attributes will be loaded if they have
-not been already. The autoload operation only occurs for the table if it
-hasn't already been loaded; once loaded, new calls to
-:class:`~sqlalchemy.schema.Table` with the same name will not re-issue any
-reflection queries.
-
-Overriding Reflected Columns
------------------------------
-
-Individual columns can be overridden with explicit values when reflecting
-tables; this is handy for specifying custom datatypes, constraints such as
-primary keys that may not be configured within the database, etc.::
-
-    >>> mytable = Table('mytable', meta,
-    ... Column('id', Integer, primary_key=True),   # override reflected 'id' to have primary key
-    ... Column('mydata', Unicode(50)),    # override reflected 'mydata' to be Unicode
-    ... autoload=True)
-
-Reflecting Views
------------------
-
-The reflection system can also reflect views. Basic usage is the same as that
-of a table::
-
-    my_view = Table("some_view", metadata, autoload=True)
-
-Above, ``my_view`` is a :class:`~sqlalchemy.schema.Table` object with
-:class:`~sqlalchemy.schema.Column` objects representing the names and types of
-each column within the view "some_view".
-
-Usually, it's desired to have at least a primary key constraint when
-reflecting a view, if not foreign keys as well. View reflection doesn't
-extrapolate these constraints.
-
-Use the "override" technique for this, specifying explicitly those columns
-which are part of the primary key or have foreign key constraints::
-
-    my_view = Table("some_view", metadata,
-                    Column("view_id", Integer, primary_key=True),
-                    Column("related_thing", Integer, ForeignKey("othertable.thing_id")),
-                    autoload=True
-    )
-
-Reflecting All Tables at Once
------------------------------
-
-The :class:`~sqlalchemy.schema.MetaData` object can also get a listing of
-tables and reflect the full set. This is achieved by using the
-:func:`~sqlalchemy.schema.MetaData.reflect` method. After calling it, all
-located tables are present within the :class:`~sqlalchemy.schema.MetaData`
-object's dictionary of tables::
-
-    meta = MetaData()
-    meta.reflect(bind=someengine)
-    users_table = meta.tables['users']
-    addresses_table = meta.tables['addresses']
-
-``metadata.reflect()`` also provides a handy way to clear or delete all the rows in a database::
-
-    meta = MetaData()
-    meta.reflect(bind=someengine)
-    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"::
-
-    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:: sqlalchemy.engine.reflection.Inspector
-    :members:
-    :undoc-members:
-    :show-inheritance:
-
-
-.. _metadata_defaults:
-
-Column Insert/Update Defaults
-==============================
-
-SQLAlchemy provides a very rich featureset regarding column level events which
-take place during INSERT and UPDATE statements. Options include:
-
-* Scalar values used as defaults during INSERT and UPDATE operations
-* Python functions which execute upon INSERT and UPDATE operations
-* SQL expressions which are embedded in INSERT statements (or in some cases execute beforehand)
-* SQL expressions which are embedded in UPDATE statements
-* Server side default values used during INSERT
-* Markers for server-side triggers used during UPDATE
-
-The general rule for all insert/update defaults is that they only take effect
-if no value for a particular column is passed as an ``execute()`` parameter;
-otherwise, the given value is used.
-
-Scalar Defaults
----------------
-
-The simplest kind of default is a scalar value used as the default value of a column::
-
-    Table("mytable", meta,
-        Column("somecolumn", Integer, default=12)
-    )
-
-Above, the value "12" will be bound as the column value during an INSERT if no
-other value is supplied.
-
-A scalar value may also be associated with an UPDATE statement, though this is
-not very common (as UPDATE statements are usually looking for dynamic
-defaults)::
-
-    Table("mytable", meta,
-        Column("somecolumn", Integer, onupdate=25)
-    )
-
-
-Python-Executed Functions
--------------------------
-
-The ``default`` and ``onupdate`` keyword arguments also accept Python
-functions. These functions are invoked at the time of insert or update if no
-other value for that column is supplied, and the value returned is used for
-the column's value. Below illustrates a crude "sequence" that assigns an
-incrementing counter to a primary key column::
-
-    # a function which counts upwards
-    i = 0
-    def mydefault():
-        global i
-        i += 1
-        return i
-
-    t = Table("mytable", meta,
-        Column('id', Integer, primary_key=True, default=mydefault),
-    )
-
-It should be noted that for real "incrementing sequence" behavior, the
-built-in capabilities of the database should normally be used, which may
-include sequence objects or other autoincrementing capabilities. For primary
-key columns, SQLAlchemy will in most cases use these capabilities
-automatically. See the API documentation for
-:class:`~sqlalchemy.schema.Column` including the ``autoincrement`` flag, as
-well as the section on :class:`~sqlalchemy.schema.Sequence` later in this
-chapter for background on standard primary key generation techniques.
-
-To illustrate onupdate, we assign the Python ``datetime`` function ``now`` to
-the ``onupdate`` attribute::
-
-    import datetime
-
-    t = Table("mytable", meta,
-        Column('id', Integer, primary_key=True),
-
-        # define 'last_updated' to be populated with datetime.now()
-        Column('last_updated', DateTime, onupdate=datetime.datetime.now),
-    )
-
-When an update statement executes and no value is passed for ``last_updated``,
-the ``datetime.datetime.now()`` Python function is executed and its return
-value used as the value for ``last_updated``. Notice that we provide ``now``
-as the function itself without calling it (i.e. there are no parenthesis
-following) - SQLAlchemy will execute the function at the time the statement
-executes.
-
-Context-Sensitive Default Functions
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The Python functions used by ``default`` and ``onupdate`` may also make use of
-the current statement's context in order to determine a value. The `context`
-of a statement is an internal SQLAlchemy object which contains all information
-about the statement being executed, including its source expression, the
-parameters associated with it and the cursor. The typical use case for this
-context with regards to default generation is to have access to the other
-values being inserted or updated on the row. To access the context, provide a
-function that accepts a single ``context`` argument::
-
-    def mydefault(context):
-        return context.current_parameters['counter'] + 12
-
-    t = Table('mytable', meta,
-        Column('counter', Integer),
-        Column('counter_plus_twelve', Integer, default=mydefault, onupdate=mydefault)
-    )
-
-Above we illustrate a default function which will execute for all INSERT and
-UPDATE statements where a value for ``counter_plus_twelve`` was otherwise not
-provided, and the value will be that of whatever value is present in the
-execution for the ``counter`` column, plus the number 12.
-
-While the context object passed to the default function has many attributes,
-the ``current_parameters`` member is a special member provided only during the
-execution of a default function for the purposes of deriving defaults from its
-existing values. For a single statement that is executing many sets of bind
-parameters, the user-defined function is called for each set of parameters,
-and ``current_parameters`` will be provided with each individual parameter set
-for each execution.
-
-SQL Expressions
----------------
-
-The "default" and "onupdate" keywords may also be passed SQL expressions,
-including select statements or direct function calls::
-
-    t = Table("mytable", meta,
-        Column('id', Integer, primary_key=True),
-
-        # define 'create_date' to default to now()
-        Column('create_date', DateTime, default=func.now()),
-
-        # define 'key' to pull its default from the 'keyvalues' table
-        Column('key', String(20), default=keyvalues.select(keyvalues.c.type='type1', limit=1)),
-
-        # define 'last_modified' to use the current_timestamp SQL function on update
-        Column('last_modified', DateTime, onupdate=func.utc_timestamp())
-        )
-
-Above, the ``create_date`` column will be populated with the result of the
-``now()`` SQL function (which, depending on backend, compiles into ``NOW()``
-or ``CURRENT_TIMESTAMP`` in most cases) during an INSERT statement, and the
-``key`` column with the result of a SELECT subquery from another table. The
-``last_modified`` column will be populated with the value of
-``UTC_TIMESTAMP()``, a function specific to MySQL, when an UPDATE statement is
-emitted for this table.
-
-Note that when using ``func`` functions, unlike when using Python `datetime`
-functions we *do* call the function, i.e. with parenthesis "()" - this is
-because what we want in this case is the return value of the function, which
-is the SQL expression construct that will be rendered into the INSERT or
-UPDATE statement.
-
-The above SQL functions are usually executed "inline" with the INSERT or
-UPDATE statement being executed, meaning, a single statement is executed which
-embeds the given expressions or subqueries within the VALUES or SET clause of
-the statement. Although in some cases, the function is "pre-executed" in a
-SELECT statement of its own beforehand. This happens when all of the following
-is true:
-
-* the column is a primary key column
-* the database dialect does not support a usable ``cursor.lastrowid`` accessor
-  (or equivalent); this currently includes PostgreSQL, Oracle, and Firebird, as
-  well as some MySQL dialects.
-* the dialect does not support the "RETURNING" clause or similar, or the
-  ``implicit_returning`` flag is set to ``False`` for the dialect. Dialects
-  which support RETURNING currently include Postgresql, Oracle, Firebird, and
-  MS-SQL.
-* the statement is a single execution, i.e. only supplies one set of
-  parameters and doesn't use "executemany" behavior
-* the ``inline=True`` flag is not set on the
-  :class:`~sqlalchemy.sql.expression.Insert()` or
-  :class:`~sqlalchemy.sql.expression.Update()` construct, and the statement has
-  not defined an explicit `returning()` clause.
-
-Whether or not the default generation clause "pre-executes" is not something
-that normally needs to be considered, unless it is being addressed for
-performance reasons.
-
-When the statement is executed with a single set of parameters (that is, it is
-not an "executemany" style execution), the returned
-:class:`~sqlalchemy.engine.ResultProxy` will contain a collection
-accessible via ``result.postfetch_cols()`` which contains a list of all
-:class:`~sqlalchemy.schema.Column` objects which had an inline-executed
-default. Similarly, all parameters which were bound to the statement,
-including all Python and SQL expressions which were pre-executed, are present
-in the ``last_inserted_params()`` or ``last_updated_params()`` collections on
-:class:`~sqlalchemy.engine.ResultProxy`. The ``inserted_primary_key``
-collection contains a list of primary key values for the row inserted (a list
-so that single-column and composite-column primary keys are represented in the
-same format).
-
-Server Side Defaults
---------------------
-
-A variant on the SQL expression default is the ``server_default``, which gets
-placed in the CREATE TABLE statement during a ``create()`` operation:
-
-.. sourcecode:: python+sql
-
-    t = Table('test', meta,
-        Column('abc', String(20), server_default='abc'),
-        Column('created_at', DateTime, server_default=text("sysdate"))
-    )
-
-A create call for the above table will produce::
-
-    CREATE TABLE test (
-        abc varchar(20) default 'abc',
-        created_at datetime default sysdate
-    )
-
-The behavior of ``server_default`` is similar to that of a regular SQL
-default; if it's placed on a primary key column for a database which doesn't
-have a way to "postfetch" the ID, and the statement is not "inlined", the SQL
-expression is pre-executed; otherwise, SQLAlchemy lets the default fire off on
-the database side normally.
-
-.. _triggered_columns:
-
-Triggered Columns
-------------------
-
-Columns with values set by a database trigger or other external process may be
-called out using :class:`.FetchedValue` as a marker::
-
-    t = Table('test', meta,
-        Column('abc', String(20), server_default=FetchedValue()),
-        Column('def', String(20), server_onupdate=FetchedValue())
-    )
-
-.. versionchanged:: 0.8.0b2,0.7.10
-    The ``for_update`` argument on :class:`.FetchedValue` is set automatically
-    when specified as the ``server_onupdate`` argument.  If using an older version,
-    specify the onupdate above as ``server_onupdate=FetchedValue(for_update=True)``.
-
-These markers do not emit a "default" clause when the table is created,
-however they do set the same internal flags as a static ``server_default``
-clause, providing hints to higher-level tools that a "post-fetch" of these
-rows should be performed after an insert or update.
-
-.. note::
-
-    It's generally not appropriate to use :class:`.FetchedValue` in
-    conjunction with a primary key column, particularly when using the
-    ORM or any other scenario where the :attr:`.ResultProxy.inserted_primary_key`
-    attribute is required.  This is becaue the "post-fetch" operation requires
-    that the primary key value already be available, so that the
-    row can be selected on its primary key.
-
-    For a server-generated primary key value, all databases provide special
-    accessors or other techniques in order to acquire the "last inserted
-    primary key" column of a table.  These mechanisms aren't affected by the presence
-    of :class:`.FetchedValue`.  For special situations where triggers are
-    used to generate primary key values, and the database in use does not
-    support the ``RETURNING`` clause, it may be necessary to forego the usage
-    of the trigger and instead apply the SQL expression or function as a
-    "pre execute" expression::
-
-        t = Table('test', meta,
-                Column('abc', MyType, default=func.generate_new_value(), primary_key=True)
-        )
-
-    Where above, when :meth:`.Table.insert` is used,
-    the ``func.generate_new_value()`` expression will be pre-executed
-    in the context of a scalar ``SELECT`` statement, and the new value will
-    be applied to the subsequent ``INSERT``, while at the same time being
-    made available to the :attr:`.ResultProxy.inserted_primary_key`
-    attribute.
-
-
-Defining Sequences
--------------------
-
-SQLAlchemy represents database sequences using the
-:class:`~sqlalchemy.schema.Sequence` object, which is considered to be a
-special case of "column default". It only has an effect on databases which
-have explicit support for sequences, which currently includes Postgresql,
-Oracle, and Firebird. The :class:`~sqlalchemy.schema.Sequence` object is
-otherwise ignored.
-
-The :class:`~sqlalchemy.schema.Sequence` may be placed on any column as a
-"default" generator to be used during INSERT operations, and can also be
-configured to fire off during UPDATE operations if desired. It is most
-commonly used in conjunction with a single integer primary key column::
-
-    table = Table("cartitems", meta,
-        Column("cart_id", Integer, Sequence('cart_id_seq'), primary_key=True),
-        Column("description", String(40)),
-        Column("createdate", DateTime())
-    )
-
-Where above, the table "cartitems" is associated with a sequence named
-"cart_id_seq". When INSERT statements take place for "cartitems", and no value
-is passed for the "cart_id" column, the "cart_id_seq" sequence will be used to
-generate a value.
-
-When the :class:`~sqlalchemy.schema.Sequence` is associated with a table,
-CREATE and DROP statements issued for that table will also issue CREATE/DROP
-for the sequence object as well, thus "bundling" the sequence object with its
-parent table.
-
-The :class:`~sqlalchemy.schema.Sequence` object also implements special
-functionality to accommodate Postgresql's SERIAL datatype. The SERIAL type in
-PG automatically generates a sequence that is used implicitly during inserts.
-This means that if a :class:`~sqlalchemy.schema.Table` object defines a
-:class:`~sqlalchemy.schema.Sequence` on its primary key column so that it
-works with Oracle and Firebird, the :class:`~sqlalchemy.schema.Sequence` would
-get in the way of the "implicit" sequence that PG would normally use. For this
-use case, add the flag ``optional=True`` to the
-:class:`~sqlalchemy.schema.Sequence` object - this indicates that the
-:class:`~sqlalchemy.schema.Sequence` should only be used if the database
-provides no other option for generating primary key identifiers.
-
-The :class:`~sqlalchemy.schema.Sequence` object also has the ability to be
-executed standalone like a SQL expression, which has the effect of calling its
-"next value" function::
-
-    seq = Sequence('some_sequence')
-    nextid = connection.execute(seq)
-
-Default Objects API
--------------------
-
-.. autoclass:: ColumnDefault
-    :show-inheritance:
-
-.. autoclass:: DefaultClause
-    :show-inheritance:
-
-.. autoclass:: DefaultGenerator
-    :show-inheritance:
-
-.. autoclass:: FetchedValue
-    :show-inheritance:
-
-.. autoclass:: PassiveDefault
-    :show-inheritance:
-
-.. autoclass:: Sequence
-    :show-inheritance:
-    :members:
-
-Defining Constraints and Indexes
-=================================
-
-.. _metadata_foreignkeys:
-.. _metadata_constraints:
-
-Defining Foreign Keys
----------------------
-
-A *foreign key* in SQL is a table-level construct that constrains one or more
-columns in that table to only allow values that are present in a different set
-of columns, typically but not always located on a different table. We call the
-columns which are constrained the *foreign key* columns and the columns which
-they are constrained towards the *referenced* columns. The referenced columns
-almost always define the primary key for their owning table, though there are
-exceptions to this. The foreign key is the "joint" that connects together
-pairs of rows which have a relationship with each other, and SQLAlchemy
-assigns very deep importance to this concept in virtually every area of its
-operation.
-
-In SQLAlchemy as well as in DDL, foreign key constraints can be defined as
-additional attributes within the table clause, or for single-column foreign
-keys they may optionally be specified within the definition of a single
-column. The single column foreign key is more common, and at the column level
-is specified by constructing a :class:`~sqlalchemy.schema.ForeignKey` object
-as an argument to a :class:`~sqlalchemy.schema.Column` object::
-
-    user_preference = Table('user_preference', metadata,
-        Column('pref_id', Integer, primary_key=True),
-        Column('user_id', Integer, ForeignKey("user.user_id"), nullable=False),
-        Column('pref_name', String(40), nullable=False),
-        Column('pref_value', String(100))
-    )
-
-Above, we define a new table ``user_preference`` for which each row must
-contain a value in the ``user_id`` column that also exists in the ``user``
-table's ``user_id`` column.
-
-The argument to :class:`~sqlalchemy.schema.ForeignKey` is most commonly a
-string of the form *<tablename>.<columnname>*, or for a table in a remote
-schema or "owner" of the form *<schemaname>.<tablename>.<columnname>*. It may
-also be an actual :class:`~sqlalchemy.schema.Column` object, which as we'll
-see later is accessed from an existing :class:`~sqlalchemy.schema.Table`
-object via its ``c`` collection::
-
-    ForeignKey(user.c.user_id)
-
-The advantage to using a string is that the in-python linkage between ``user``
-and ``user_preference`` is resolved only when first needed, so that table
-objects can be easily spread across multiple modules and defined in any order.
-
-Foreign keys may also be defined at the table level, using the
-:class:`~sqlalchemy.schema.ForeignKeyConstraint` object. This object can
-describe a single- or multi-column foreign key. A multi-column foreign key is
-known as a *composite* foreign key, and almost always references a table that
-has a composite primary key. Below we define a table ``invoice`` which has a
-composite primary key::
-
-    invoice = Table('invoice', metadata,
-        Column('invoice_id', Integer, primary_key=True),
-        Column('ref_num', Integer, primary_key=True),
-        Column('description', String(60), nullable=False)
-    )
-
-And then a table ``invoice_item`` with a composite foreign key referencing
-``invoice``::
-
-    invoice_item = Table('invoice_item', metadata,
-        Column('item_id', Integer, primary_key=True),
-        Column('item_name', String(60), nullable=False),
-        Column('invoice_id', Integer, nullable=False),
-        Column('ref_num', Integer, nullable=False),
-        ForeignKeyConstraint(['invoice_id', 'ref_num'], ['invoice.invoice_id', 'invoice.ref_num'])
-    )
-
-It's important to note that the
-:class:`~sqlalchemy.schema.ForeignKeyConstraint` is the only way to define a
-composite foreign key. While we could also have placed individual
-:class:`~sqlalchemy.schema.ForeignKey` objects on both the
-``invoice_item.invoice_id`` and ``invoice_item.ref_num`` columns, SQLAlchemy
-would not be aware that these two values should be paired together - it would
-be two individual foreign key constraints instead of a single composite
-foreign key referencing two columns.
-
-.. _use_alter:
-
-Creating/Dropping Foreign Key Constraints via ALTER
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-In all the above examples, the :class:`~sqlalchemy.schema.ForeignKey` object
-causes the "REFERENCES" keyword to be added inline to a column definition
-within a "CREATE TABLE" statement when
-:func:`~sqlalchemy.schema.MetaData.create_all` is issued, and
-:class:`~sqlalchemy.schema.ForeignKeyConstraint` invokes the "CONSTRAINT"
-keyword inline with "CREATE TABLE". There are some cases where this is
-undesireable, particularly when two tables reference each other mutually, each
-with a foreign key referencing the other. In such a situation at least one of
-the foreign key constraints must be generated after both tables have been
-built. To support such a scheme, :class:`~sqlalchemy.schema.ForeignKey` and
-:class:`~sqlalchemy.schema.ForeignKeyConstraint` offer the flag
-``use_alter=True``. When using this flag, the constraint will be generated
-using a definition similar to "ALTER TABLE <tablename> ADD CONSTRAINT <name>
-...". Since a name is required, the ``name`` attribute must also be specified.
-For example::
-
-    node = Table('node', meta,
-        Column('node_id', Integer, primary_key=True),
-        Column('primary_element', Integer,
-            ForeignKey('element.element_id', use_alter=True, name='fk_node_element_id')
-        )
-    )
-
-    element = Table('element', meta,
-        Column('element_id', Integer, primary_key=True),
-        Column('parent_node_id', Integer),
-        ForeignKeyConstraint(
-            ['parent_node_id'],
-            ['node.node_id'],
-            use_alter=True,
-            name='fk_element_parent_node_id'
-        )
-    )
-
-ON UPDATE and ON DELETE
-~~~~~~~~~~~~~~~~~~~~~~~
-
-Most databases support *cascading* of foreign key values, that is the when a
-parent row is updated the new value is placed in child rows, or when the
-parent row is deleted all corresponding child rows are set to null or deleted.
-In data definition language these are specified using phrases like "ON UPDATE
-CASCADE", "ON DELETE CASCADE", and "ON DELETE SET NULL", corresponding to
-foreign key constraints. The phrase after "ON UPDATE" or "ON DELETE" may also
-other allow other phrases that are specific to the database in use. The
-:class:`~sqlalchemy.schema.ForeignKey` and
-:class:`~sqlalchemy.schema.ForeignKeyConstraint` objects support the
-generation of this clause via the ``onupdate`` and ``ondelete`` keyword
-arguments. The value is any string which will be output after the appropriate
-"ON UPDATE" or "ON DELETE" phrase::
-
-    child = Table('child', meta,
-        Column('id', Integer,
-                ForeignKey('parent.id', onupdate="CASCADE", ondelete="CASCADE"),
-                primary_key=True
-        )
-    )
-
-    composite = Table('composite', meta,
-        Column('id', Integer, primary_key=True),
-        Column('rev_id', Integer),
-        Column('note_id', Integer),
-        ForeignKeyConstraint(
-                    ['rev_id', 'note_id'],
-                    ['revisions.id', 'revisions.note_id'],
-                    onupdate="CASCADE", ondelete="SET NULL"
-        )
-    )
-
-Note that these clauses are not supported on SQLite, and require ``InnoDB``
-tables when used with MySQL. They may also not be supported on other
-databases.
-
-
-UNIQUE Constraint
------------------
-
-Unique constraints can be created anonymously on a single column using the
-``unique`` keyword on :class:`~sqlalchemy.schema.Column`. Explicitly named
-unique constraints and/or those with multiple columns are created via the
-:class:`~sqlalchemy.schema.UniqueConstraint` table-level construct.
-
-.. sourcecode:: python+sql
-
-    meta = MetaData()
-    mytable = Table('mytable', meta,
-
-        # per-column anonymous unique constraint
-        Column('col1', Integer, unique=True),
-
-        Column('col2', Integer),
-        Column('col3', Integer),
-
-        # explicit/composite unique constraint.  'name' is optional.
-        UniqueConstraint('col2', 'col3', name='uix_1')
-        )
-
-CHECK Constraint
-----------------
-
-Check constraints can be named or unnamed and can be created at the Column or
-Table level, using the :class:`~sqlalchemy.schema.CheckConstraint` construct.
-The text of the check constraint is passed directly through to the database,
-so there is limited "database independent" behavior. Column level check
-constraints generally should only refer to the column to which they are
-placed, while table level constraints can refer to any columns in the table.
-
-Note that some databases do not actively support check constraints such as
-MySQL.
-
-.. sourcecode:: python+sql
-
-    meta = MetaData()
-    mytable = Table('mytable', meta,
-
-        # per-column CHECK constraint
-        Column('col1', Integer, CheckConstraint('col1>5')),
-
-        Column('col2', Integer),
-        Column('col3', Integer),
-
-        # table level CHECK constraint.  'name' is optional.
-        CheckConstraint('col2 > col3 + 5', name='check1')
-        )
-
-    {sql}mytable.create(engine)
-    CREATE TABLE mytable (
-        col1 INTEGER  CHECK (col1>5),
-        col2 INTEGER,
-        col3 INTEGER,
-        CONSTRAINT check1  CHECK (col2 > col3 + 5)
-    ){stop}
-
-Setting up Constraints when using the Declarative ORM Extension
-----------------------------------------------------------------
-
-The :class:`.Table` is the SQLAlchemy Core construct that allows one to define
-table metadata, which among other things can be used by the SQLAlchemy ORM
-as a target to map a class.  The :ref:`Declarative <declarative_toplevel>`
-extension allows the :class:`.Table` object to be created automatically, given
-the contents of the table primarily as a mapping of :class:`.Column` objects.
-
-To apply table-level constraint objects such as :class:`.ForeignKeyConstraint`
-to a table defined using Declarative, use the ``__table_args__`` attribute,
-described at :ref:`declarative_table_args`.
-
-Constraints API
----------------
-.. autoclass:: Constraint
-    :show-inheritance:
-
-.. autoclass:: CheckConstraint
-    :show-inheritance:
-
-.. autoclass:: ColumnCollectionConstraint
-    :show-inheritance:
-
-.. autoclass:: ForeignKey
-    :members:
-    :show-inheritance:
-
-.. autoclass:: ForeignKeyConstraint
-    :members:
-    :show-inheritance:
-
-.. autoclass:: PrimaryKeyConstraint
-    :show-inheritance:
-
-.. autoclass:: UniqueConstraint
-    :show-inheritance:
-
-.. _schema_indexes:
-
-Indexes
--------
-
-Indexes can be created anonymously (using an auto-generated name ``ix_<column
-label>``) for a single column using the inline ``index`` keyword on
-:class:`~sqlalchemy.schema.Column`, which also modifies the usage of
-``unique`` to apply the uniqueness to the index itself, instead of adding a
-separate UNIQUE constraint. For indexes with specific names or which encompass
-more than one column, use the :class:`~sqlalchemy.schema.Index` construct,
-which requires a name.
-
-Below we illustrate a :class:`~sqlalchemy.schema.Table` with several
-:class:`~sqlalchemy.schema.Index` objects associated. The DDL for "CREATE
-INDEX" is issued right after the create statements for the table:
-
-.. sourcecode:: python+sql
-
-    meta = MetaData()
-    mytable = Table('mytable', meta,
-        # an indexed column, with index "ix_mytable_col1"
-        Column('col1', Integer, index=True),
-
-        # a uniquely indexed column with index "ix_mytable_col2"
-        Column('col2', Integer, index=True, unique=True),
-
-        Column('col3', Integer),
-        Column('col4', Integer),
-
-        Column('col5', Integer),
-        Column('col6', Integer),
-        )
-
-    # place an index on col3, col4
-    Index('idx_col34', mytable.c.col3, mytable.c.col4)
-
-    # place a unique index on col5, col6
-    Index('myindex', mytable.c.col5, mytable.c.col6, unique=True)
-
-    {sql}mytable.create(engine)
-    CREATE TABLE mytable (
-        col1 INTEGER,
-        col2 INTEGER,
-        col3 INTEGER,
-        col4 INTEGER,
-        col5 INTEGER,
-        col6 INTEGER
-    )
-    CREATE INDEX ix_mytable_col1 ON mytable (col1)
-    CREATE UNIQUE INDEX ix_mytable_col2 ON mytable (col2)
-    CREATE UNIQUE INDEX myindex ON mytable (col5, col6)
-    CREATE INDEX idx_col34 ON mytable (col3, col4){stop}
-
-Note in the example above, the :class:`.Index` construct is created
-externally to the table which it corresponds, using :class:`.Column`
-objects directly.  :class:`.Index` also supports
-"inline" definition inside the :class:`.Table`, using string names to
-identify columns::
-
-    meta = MetaData()
-    mytable = Table('mytable', meta,
-        Column('col1', Integer),
-
-        Column('col2', Integer),
-
-        Column('col3', Integer),
-        Column('col4', Integer),
-
-        # place an index on col1, col2
-        Index('idx_col12', 'col1', 'col2'),
-
-        # place a unique index on col3, col4
-        Index('idx_col34', 'col3', 'col4', unique=True)
-    )
-
-.. versionadded:: 0.7
-    Support of "inline" definition inside the :class:`.Table`
-    for :class:`.Index`\ .
-
-The :class:`~sqlalchemy.schema.Index` object also supports its own ``create()`` method:
-
-.. sourcecode:: python+sql
-
-    i = Index('someindex', mytable.c.col5)
-    {sql}i.create(engine)
-    CREATE INDEX someindex ON mytable (col5){stop}
-
-.. _schema_indexes_functional:
-
-Functional Indexes
-~~~~~~~~~~~~~~~~~~~
-
-:class:`.Index` supports SQL and function expressions, as supported by the
-target backend.  To create an index against a column using a descending
-value, the :meth:`.ColumnElement.desc` modifier may be used::
-
-    from sqlalchemy import Index
-
-    Index('someindex', mytable.c.somecol.desc())
-
-Or with a backend that supports functional indexes such as Postgresql,
-a "case insensitive" index can be created using the ``lower()`` function::
-
-    from sqlalchemy import func, Index
-
-    Index('someindex', func.lower(mytable.c.somecol))
-
-.. versionadded:: 0.8 :class:`.Index` supports SQL expressions and functions
-   as well as plain columns.
-
-Index API
----------
-
-.. autoclass:: Index
-    :show-inheritance:
-    :members:
-
-.. _metadata_ddl:
-
-Customizing DDL
-===============
-
-In the preceding sections we've discussed a variety of schema constructs
-including :class:`~sqlalchemy.schema.Table`,
-:class:`~sqlalchemy.schema.ForeignKeyConstraint`,
-:class:`~sqlalchemy.schema.CheckConstraint`, and
-:class:`~sqlalchemy.schema.Sequence`. Throughout, we've relied upon the
-``create()`` and :func:`~sqlalchemy.schema.MetaData.create_all` methods of
-:class:`~sqlalchemy.schema.Table` and :class:`~sqlalchemy.schema.MetaData` in
-order to issue data definition language (DDL) for all constructs. When issued,
-a pre-determined order of operations is invoked, and DDL to create each table
-is created unconditionally including all constraints and other objects
-associated with it. For more complex scenarios where database-specific DDL is
-required, SQLAlchemy offers two techniques which can be used to add any DDL
-based on any condition, either accompanying the standard generation of tables
-or by itself.
-
-.. _schema_ddl_sequences:
-
-Controlling DDL Sequences
--------------------------
-
-The ``sqlalchemy.schema`` package contains SQL expression constructs that
-provide DDL expressions. For example, to produce a ``CREATE TABLE`` statement:
-
-.. sourcecode:: python+sql
-
-    from sqlalchemy.schema import CreateTable
-    {sql}engine.execute(CreateTable(mytable))
-    CREATE TABLE mytable (
-        col1 INTEGER,
-        col2 INTEGER,
-        col3 INTEGER,
-        col4 INTEGER,
-        col5 INTEGER,
-        col6 INTEGER
-    ){stop}
-
-Above, the :class:`~sqlalchemy.schema.CreateTable` construct works like any
-other expression construct (such as ``select()``, ``table.insert()``, etc.). A
-full reference of available constructs is in :ref:`schema_api_ddl`.
-
-The DDL constructs all extend a common base class which provides the
-capability to be associated with an individual
-:class:`~sqlalchemy.schema.Table` or :class:`~sqlalchemy.schema.MetaData`
-object, to be invoked upon create/drop events. Consider the example of a table
-which contains a CHECK constraint:
-
-.. sourcecode:: python+sql
-
-    users = Table('users', metadata,
-                   Column('user_id', Integer, primary_key=True),
-                   Column('user_name', String(40), nullable=False),
-                   CheckConstraint('length(user_name) >= 8',name="cst_user_name_length")
-                   )
-
-    {sql}users.create(engine)
-    CREATE TABLE users (
-        user_id SERIAL NOT NULL,
-        user_name VARCHAR(40) NOT NULL,
-        PRIMARY KEY (user_id),
-        CONSTRAINT cst_user_name_length  CHECK (length(user_name) >= 8)
-    ){stop}
-
-The above table contains a column "user_name" which is subject to a CHECK
-constraint that validates that the length of the string is at least eight
-characters. When a ``create()`` is issued for this table, DDL for the
-:class:`~sqlalchemy.schema.CheckConstraint` will also be issued inline within
-the table definition.
-
-The :class:`~sqlalchemy.schema.CheckConstraint` construct can also be
-constructed externally and associated with the
-:class:`~sqlalchemy.schema.Table` afterwards::
-
-    constraint = CheckConstraint('length(user_name) >= 8',name="cst_user_name_length")
-    users.append_constraint(constraint)
-
-So far, the effect is the same. However, if we create DDL elements
-corresponding to the creation and removal of this constraint, and associate
-them with the :class:`.Table` as events, these new events
-will take over the job of issuing DDL for the constraint. Additionally, the
-constraint will be added via ALTER:
-
-.. sourcecode:: python+sql
-
-    from sqlalchemy import event
-
-    event.listen(
-        users,
-        "after_create",
-        AddConstraint(constraint)
-    )
-    event.listen(
-        users,
-        "before_drop",
-        DropConstraint(constraint)
-    )
-
-    {sql}users.create(engine)
-    CREATE TABLE users (
-        user_id SERIAL NOT NULL,
-        user_name VARCHAR(40) NOT NULL,
-        PRIMARY KEY (user_id)
-    )
-
-    ALTER TABLE users ADD CONSTRAINT cst_user_name_length  CHECK (length(user_name) >= 8){stop}
-
-    {sql}users.drop(engine)
-    ALTER TABLE users DROP CONSTRAINT cst_user_name_length
-    DROP TABLE users{stop}
-
-The real usefulness of the above becomes clearer once we illustrate the
-:meth:`.DDLElement.execute_if` method.  This method returns a modified form of
-the DDL callable which will filter on criteria before responding to a
-received event.   It accepts a parameter ``dialect``, which is the string
-name of a dialect or a tuple of such, which will limit the execution of the
-item to just those dialects.  It also accepts a ``callable_`` parameter which
-may reference a Python callable which will be invoked upon event reception,
-returning ``True`` or ``False`` indicating if the event should proceed.
-
-If our :class:`~sqlalchemy.schema.CheckConstraint` was only supported by
-Postgresql and not other databases, we could limit its usage to just that dialect::
-
-    event.listen(
-        users,
-        'after_create',
-        AddConstraint(constraint).execute_if(dialect='postgresql')
-    )
-    event.listen(
-        users,
-        'before_drop',
-        DropConstraint(constraint).execute_if(dialect='postgresql')
-    )
-
-Or to any set of dialects::
-
-    event.listen(
-        users,
-        "after_create",
-        AddConstraint(constraint).execute_if(dialect=('postgresql', 'mysql'))
-    )
-    event.listen(
-        users,
-        "before_drop",
-        DropConstraint(constraint).execute_if(dialect=('postgresql', 'mysql'))
-    )
-
-When using a callable, the callable is passed the ddl element, the
-:class:`.Table` or :class:`.MetaData`
-object whose "create" or "drop" event is in progress, and the
-:class:`.Connection` object being used for the
-operation, as well as additional information as keyword arguments. The
-callable can perform checks, such as whether or not a given item already
-exists. Below we define ``should_create()`` and ``should_drop()`` callables
-that check for the presence of our named constraint:
-
-.. sourcecode:: python+sql
-
-    def should_create(ddl, target, connection, **kw):
-        row = connection.execute("select conname from pg_constraint where conname='%s'" % ddl.element.name).scalar()
-        return not bool(row)
-
-    def should_drop(ddl, target, connection, **kw):
-        return not should_create(ddl, target, connection, **kw)
-
-    event.listen(
-        users,
-        "after_create",
-        AddConstraint(constraint).execute_if(callable_=should_create)
-    )
-    event.listen(
-        users,
-        "before_drop",
-        DropConstraint(constraint).execute_if(callable_=should_drop)
-    )
-
-    {sql}users.create(engine)
-    CREATE TABLE users (
-        user_id SERIAL NOT NULL,
-        user_name VARCHAR(40) NOT NULL,
-        PRIMARY KEY (user_id)
-    )
-
-    select conname from pg_constraint where conname='cst_user_name_length'
-    ALTER TABLE users ADD CONSTRAINT cst_user_name_length  CHECK (length(user_name) >= 8){stop}
-
-    {sql}users.drop(engine)
-    select conname from pg_constraint where conname='cst_user_name_length'
-    ALTER TABLE users DROP CONSTRAINT cst_user_name_length
-    DROP TABLE users{stop}
-
-Custom DDL
-----------
-
-Custom DDL phrases are most easily achieved using the
-:class:`~sqlalchemy.schema.DDL` construct. This construct works like all the
-other DDL elements except it accepts a string which is the text to be emitted:
-
-.. sourcecode:: python+sql
-
-    event.listen(
-        metadata,
-        "after_create",
-        DDL("ALTER TABLE users ADD CONSTRAINT "
-            "cst_user_name_length "
-            " CHECK (length(user_name) >= 8)")
-    )
-
-A more comprehensive method of creating libraries of DDL constructs is to use
-custom compilation - see :ref:`sqlalchemy.ext.compiler_toplevel` for
-details.
-
-.. _schema_api_ddl:
-
-DDL Expression Constructs API
------------------------------
-
-.. autoclass:: DDLElement
-    :members:
-    :undoc-members:
-    :show-inheritance:
-
-.. autoclass:: DDL
-    :members:
-    :undoc-members:
-    :show-inheritance:
-
-.. autoclass:: CreateTable
-    :members:
-    :undoc-members:
-    :show-inheritance:
-
-.. autoclass:: DropTable
-    :members:
-    :undoc-members:
-    :show-inheritance:
-
-.. autoclass:: CreateColumn
-    :members:
-    :undoc-members:
-    :show-inheritance:
-
-.. autoclass:: CreateSequence
-    :members:
-    :undoc-members:
-    :show-inheritance:
-
-.. autoclass:: DropSequence
-    :members:
-    :undoc-members:
-    :show-inheritance:
-
-.. autoclass:: CreateIndex
-    :members:
-    :undoc-members:
-    :show-inheritance:
-
-.. autoclass:: DropIndex
-    :members:
-    :undoc-members:
-    :show-inheritance:
-
-.. autoclass:: AddConstraint
-    :members:
-    :undoc-members:
-    :show-inheritance:
+.. toctree::
+    :maxdepth: 1
 
-.. autoclass:: DropConstraint
-    :members:
-    :undoc-members:
-    :show-inheritance:
+    metadata
+    reflection
+    defaults
+    constraints
+    ddl
 
-.. autoclass:: CreateSchema
-    :members:
-    :undoc-members:
-    :show-inheritance:
 
-.. autoclass:: DropSchema
-    :members:
-    :undoc-members:
-    :show-inheritance:
 
diff --git a/doc/build/core/selectable.rst b/doc/build/core/selectable.rst
new file mode 100644 (file)
index 0000000..341ffcc
--- /dev/null
@@ -0,0 +1,76 @@
+Selectables, Tables, FROM objects
+=================================
+
+The term "selectable" refers to any object that rows can be selected from;
+in SQLAlchemy, these objects descend from :class:`.FromClause` and their
+distinguishing feature is their :attr:`.FromClause.c` attribute, which is
+a namespace of all the columns contained within the FROM clause (these
+elements are themselves :class:`.ColumnElement` subclasses).
+
+.. module:: sqlalchemy.sql.expression
+
+.. autofunction:: alias
+
+.. autofunction:: except_
+
+.. autofunction:: except_all
+
+.. autofunction:: exists
+
+.. autofunction:: intersect
+
+.. autofunction:: intersect_all
+
+.. autofunction:: join
+
+.. autofunction:: outerjoin
+
+.. autofunction:: select
+
+.. autofunction:: subquery
+
+.. autofunction:: sqlalchemy.sql.expression.table
+
+.. autofunction:: union
+
+.. autofunction:: union_all
+
+.. autoclass:: Alias
+   :members:
+   :inherited-members:
+
+.. autoclass:: CompoundSelect
+   :members:
+   :inherited-members:
+
+.. autoclass:: CTE
+   :members:
+   :inherited-members:
+
+.. autoclass:: Executable
+   :members:
+
+
+.. autoclass:: FromClause
+   :members:
+
+
+.. autoclass:: Join
+   :members:
+   :inherited-members:
+
+.. autoclass:: Select
+   :members:
+   :inherited-members:
+
+.. autoclass:: Selectable
+   :members:
+
+
+.. autoclass:: SelectBase
+   :members:
+
+
+.. autoclass:: TableClause
+   :members:
+   :inherited-members:
diff --git a/doc/build/core/sqlelement.rst b/doc/build/core/sqlelement.rst
new file mode 100644 (file)
index 0000000..953f48c
--- /dev/null
@@ -0,0 +1,112 @@
+Column Elements and Expressions
+===============================
+
+.. module:: sqlalchemy.sql.expression
+
+The most fundamental part of the SQL expression API are the "column elements",
+which allow for basic SQL expression support.   The core of all SQL expression
+constructs is the :class:`.ClauseElement`, which is the base for several
+sub-branches.  The :class:`.ColumnElement` class is the fundamental unit
+used to construct any kind of typed SQL expression.
+
+.. autofunction:: and_
+
+.. autofunction:: asc
+
+.. autofunction:: between
+
+.. autofunction:: bindparam
+
+.. autofunction:: case
+
+.. autofunction:: cast
+
+.. autofunction:: sqlalchemy.sql.expression.column
+
+.. autofunction:: collate
+
+.. autofunction:: desc
+
+.. autofunction:: distinct
+
+.. autofunction:: extract
+
+.. autofunction:: false
+
+.. autodata:: func
+
+.. autofunction:: label
+
+.. autofunction:: literal
+
+.. autofunction:: literal_column
+
+.. autofunction:: not_
+
+.. autofunction:: null
+
+.. autofunction:: nullsfirst
+
+.. autofunction:: nullslast
+
+.. autofunction:: or_
+
+.. autofunction:: outparam
+
+.. autofunction:: over
+
+.. autofunction:: text
+
+.. autofunction:: true
+
+.. autofunction:: tuple_
+
+.. autofunction:: type_coerce
+
+.. autoclass:: BinaryExpression
+   :members:
+
+   :inherited-members:
+
+.. autoclass:: BindParameter
+   :members:
+   :inherited-members:
+
+.. autoclass:: ClauseElement
+   :members:
+
+
+.. autoclass:: ClauseList
+   :members:
+
+
+.. autoclass:: ColumnClause
+   :members:
+   :inherited-members:
+
+.. autoclass:: ColumnCollection
+   :members:
+
+
+.. autoclass:: ColumnElement
+   :members:
+   :inherited-members:
+
+.. autoclass:: sqlalchemy.sql.operators.ColumnOperators
+   :members:
+   :special-members:
+   :inherited-members:
+
+
+.. autoclass:: sqlalchemy.sql.operators.custom_op
+   :members:
+
+.. autoclass:: sqlalchemy.sql.operators.Operators
+   :members:
+   :special-members:
+
+.. autoclass:: UnaryExpression
+   :members:
+
+
+
index 1c1884b11269e9d34528df93ca995cc6ee93e9e4..ccbba5d246d956f6b701d1f862b110af69027f72 100644 (file)
@@ -41,76 +41,58 @@ type is emitted in ``CREATE TABLE``, such as ``VARCHAR`` see `SQL
 Standard Types`_ and the other sections of this chapter.
 
 .. autoclass:: BigInteger
-  :show-inheritance:
-  :members:
+   :members:
 
 .. autoclass:: Boolean
-  :show-inheritance:
-  :members:
+   :members:
 
 .. autoclass:: Date
- :show-inheritance:
- :members:
+   :members:
 
 .. autoclass:: DateTime
-   :show-inheritance:
    :members:
 
 .. autoclass:: Enum
-  :show-inheritance:
   :members: __init__, create, drop
 
 .. autoclass:: Float
-  :show-inheritance:
   :members:
 
 .. autoclass:: Integer
-  :show-inheritance:
   :members:
 
 .. autoclass:: Interval
- :show-inheritance:
- :members:
+  :members:
 
 .. autoclass:: LargeBinary
- :show-inheritance:
- :members:
+  :members:
 
 .. autoclass:: Numeric
-  :show-inheritance:
   :members:
 
 .. autoclass:: PickleType
- :show-inheritance:
- :members:
+  :members:
 
 .. autoclass:: SchemaType
-  :show-inheritance:
   :members:
   :undoc-members:
 
 .. autoclass:: SmallInteger
- :show-inheritance:
- :members:
+  :members:
 
 .. autoclass:: String
-   :show-inheritance:
    :members:
 
 .. autoclass:: Text
-   :show-inheritance:
    :members:
 
 .. autoclass:: Time
-  :show-inheritance:
   :members:
 
 .. autoclass:: Unicode
-  :show-inheritance:
   :members:
 
 .. autoclass:: UnicodeText
-   :show-inheritance:
    :members:
 
 .. _types_sqlstandard:
@@ -123,70 +105,70 @@ name when ``CREATE TABLE`` is issued.  Some types may not be supported
 on all databases.
 
 .. autoclass:: BIGINT
-  :show-inheritance:
+
 
 .. autoclass:: BINARY
-  :show-inheritance:
+
 
 .. autoclass:: BLOB
-  :show-inheritance:
+
 
 .. autoclass:: BOOLEAN
-  :show-inheritance:
+
 
 .. autoclass:: CHAR
-  :show-inheritance:
+
 
 .. autoclass:: CLOB
-  :show-inheritance:
+
 
 .. autoclass:: DATE
-  :show-inheritance:
+
 
 .. autoclass:: DATETIME
-  :show-inheritance:
+
 
 .. autoclass:: DECIMAL
-  :show-inheritance:
+
 
 .. autoclass:: FLOAT
-  :show-inheritance:
+
 
 .. autoclass:: INT
-  :show-inheritance:
+
 
 .. autoclass:: sqlalchemy.types.INTEGER
-  :show-inheritance:
+
 
 .. autoclass:: NCHAR
-  :show-inheritance:
+
 
 .. autoclass:: NVARCHAR
-  :show-inheritance:
+
 
 .. autoclass:: NUMERIC
-  :show-inheritance:
+
 
 .. autoclass:: REAL
-  :show-inheritance:
+
 
 .. autoclass:: SMALLINT
-  :show-inheritance:
+
 
 .. autoclass:: TEXT
-  :show-inheritance:
+
 
 .. autoclass:: TIME
-  :show-inheritance:
+
 
 .. autoclass:: TIMESTAMP
-  :show-inheritance:
+
 
 .. autoclass:: VARBINARY
-  :show-inheritance:
+
 
 .. autoclass:: VARCHAR
-  :show-inheritance:
+
 
 .. _types_vendor:
 
@@ -194,7 +176,7 @@ Vendor-Specific Types
 ---------------------
 
 Database-specific types are also available for import from each
-database's dialect module. See the :ref:`sqlalchemy.dialects_toplevel`
+database's dialect module. See the :ref:`dialect_toplevel`
 reference for the database you're interested in.
 
 For example, MySQL has a ``BIGINT`` type and PostgreSQL has an
@@ -300,7 +282,7 @@ to and from the database is required.
 .. autoclass:: TypeDecorator
    :members:
    :inherited-members:
-   :show-inheritance:
+
 
 TypeDecorator Recipes
 ~~~~~~~~~~~~~~~~~~~~~
@@ -738,7 +720,7 @@ is needed, use :class:`.TypeDecorator` instead.
 
 .. autoclass:: UserDefinedType
    :members:
-   :show-inheritance:
+
 
 .. _types_api:
 
@@ -747,20 +729,20 @@ Base Type API
 
 .. autoclass:: AbstractType
    :members:
-   :show-inheritance:
+
 
 .. autoclass:: TypeEngine
    :members:
-   :show-inheritance:
+
 
 .. autoclass:: Concatenable
    :members:
    :inherited-members:
-   :show-inheritance:
+
 
 .. autoclass:: NullType
-   :show-inheritance:
+
 
 .. autoclass:: Variant
-   :show-inheritance:
+
    :members: with_variant, __init__
index 99ff596d7feac371b6e2c2d648df6ebb2d45cdc8..c89bba032a2a6ea5fa6b085f0db7abedec41fe9e 100644 (file)
@@ -23,51 +23,51 @@ construction arguments, are as follows:
 
 .. autoclass:: BIGINT
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: CHAR
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: DECIMAL
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: DOUBLE
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: ENUM
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: FLOAT
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: INTEGER
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: NUMERIC
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: REAL
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: TEXT
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: TIMESTAMP
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: VARCHAR
     :members: __init__
-    :show-inheritance:
+     
 
 
 MySQL-Python
index 615d1a11dd18a6b7da770c995dbfdac8c2e4d97e..6173ffba190b9ba7aa8ab075d2eb046890268bb3 100644 (file)
@@ -26,75 +26,75 @@ construction arguments, are as follows:
 
 .. autoclass:: BIT
    :members: __init__
-   :show-inheritance:
+    
 
 .. autoclass:: CHAR
    :members: __init__
-   :show-inheritance:
+    
 
 .. autoclass:: DATETIME2
    :members: __init__
-   :show-inheritance:
+    
 
 .. autoclass:: DATETIMEOFFSET
    :members: __init__
-   :show-inheritance:
+    
 
 .. autoclass:: IMAGE
    :members: __init__
-   :show-inheritance:
+    
 
 .. autoclass:: MONEY
    :members: __init__
-   :show-inheritance:
+    
 
 .. autoclass:: NCHAR
    :members: __init__
-   :show-inheritance:
+    
 
 .. autoclass:: NTEXT
    :members: __init__
-   :show-inheritance:
+    
 
 .. autoclass:: NVARCHAR
    :members: __init__
-   :show-inheritance:
+    
 
 .. autoclass:: REAL
    :members: __init__
-   :show-inheritance:
+    
 
 .. autoclass:: SMALLDATETIME
    :members: __init__
-   :show-inheritance:
+    
 
 .. autoclass:: SMALLMONEY
    :members: __init__
-   :show-inheritance:
+    
 
 .. autoclass:: SQL_VARIANT
    :members: __init__
-   :show-inheritance:
+    
 
 .. autoclass:: TEXT
    :members: __init__
-   :show-inheritance:
+    
 
 .. autoclass:: TIME
    :members: __init__
-   :show-inheritance:
+    
 
 .. autoclass:: TINYINT
    :members: __init__
-   :show-inheritance:
+    
 
 .. autoclass:: UNIQUEIDENTIFIER
    :members: __init__
-   :show-inheritance:
+    
 
 .. autoclass:: VARCHAR
    :members: __init__
-   :show-inheritance:
+    
 
 
 PyODBC
index 1e2784554f92610cfd2f29cee7db1b81533e4c52..de71a99ac4f87bbc2fd1db802cd17dfafa06c0d0 100644 (file)
@@ -25,135 +25,135 @@ construction arguments, are as follows:
 
 .. autoclass:: BIGINT
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: BINARY
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: BIT
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: BLOB
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: BOOLEAN
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: CHAR
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: DATE
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: DATETIME
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: DECIMAL
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: DOUBLE
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: ENUM
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: FLOAT
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: INTEGER
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: LONGBLOB
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: LONGTEXT
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: MEDIUMBLOB
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: MEDIUMINT
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: MEDIUMTEXT
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: NCHAR
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: NUMERIC
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: NVARCHAR
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: REAL
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: SET
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: SMALLINT
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: TEXT
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: TIME
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: TIMESTAMP
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: TINYBLOB
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: TINYINT
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: TINYTEXT
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: VARBINARY
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: VARCHAR
     :members: __init__
-    :show-inheritance:
+     
 
 .. autoclass:: YEAR
     :members: __init__
-    :show-inheritance:
+     
 
 MySQL-Python
 --------------------
index 4be8c5b5136f6ef23b8116afedd789dfc3a4f685..32a5448775103e96907415ae3389386cfd5be7de 100644 (file)
@@ -25,31 +25,31 @@ construction arguments, are as follows:
 
 .. autoclass:: BFILE
   :members: __init__
-  :show-inheritance:
+   
 
 .. autoclass:: DOUBLE_PRECISION
    :members: __init__
-   :show-inheritance:
+    
 
 .. autoclass:: INTERVAL
   :members: __init__
-  :show-inheritance:
+   
 
 .. autoclass:: NCLOB
   :members: __init__
-  :show-inheritance:
+   
 
 .. autoclass:: NUMBER
    :members: __init__
-   :show-inheritance:
+    
 
 .. autoclass:: LONG
   :members: __init__
-  :show-inheritance:
+   
 
 .. autoclass:: RAW
   :members: __init__
-  :show-inheritance:
+   
 
 cx_Oracle
 ----------
index 3c151483f9c6a818c4dc581ebb040afbd18835ca..c5a28bacfbfbdacba44db4ac9a49ad88ecd1cf01 100644 (file)
@@ -28,7 +28,7 @@ construction arguments, are as follows:
 
 .. autoclass:: ARRAY
     :members: __init__, Comparator
-    :show-inheritance:
+
 
 .. autoclass:: Any
 
@@ -36,51 +36,51 @@ construction arguments, are as follows:
 
 .. autoclass:: BIT
     :members: __init__
-    :show-inheritance:
+
 
 .. autoclass:: BYTEA
     :members: __init__
-    :show-inheritance:
+
 
 .. autoclass:: CIDR
     :members: __init__
-    :show-inheritance:
+
 
 .. autoclass:: DOUBLE_PRECISION
     :members: __init__
-    :show-inheritance:
+
 
 .. autoclass:: ENUM
     :members: __init__, create, drop
-    :show-inheritance:
+
 
 .. autoclass:: HSTORE
     :members:
-    :show-inheritance:
+
 
 .. autoclass:: hstore
     :members:
-    :show-inheritance:
+
 
 .. autoclass:: INET
     :members: __init__
-    :show-inheritance:
+
 
 .. autoclass:: INTERVAL
     :members: __init__
-    :show-inheritance:
+
 
 .. autoclass:: MACADDR
     :members: __init__
-    :show-inheritance:
+
 
 .. autoclass:: REAL
     :members: __init__
-    :show-inheritance:
+
 
 .. autoclass:: UUID
     :members: __init__
-    :show-inheritance:
+
 
 Range Types
 ~~~~~~~~~~~
@@ -89,22 +89,22 @@ The new range column types founds in PostgreSQL 9.2 onwards are
 catered for by the following types:
 
 .. autoclass:: INT4RANGE
-   :show-inheritance:
+
 
 .. autoclass:: INT8RANGE
-   :show-inheritance:
+
 
 .. autoclass:: NUMRANGE
-   :show-inheritance:
+
 
 .. autoclass:: DATERANGE
-   :show-inheritance:
+
 
 .. autoclass:: TSRANGE
-   :show-inheritance:
+
 
 .. autoclass:: TSTZRANGE
-   :show-inheritance:
+
 
 The types above get most of their functionality from the following
 mixin:
@@ -127,7 +127,6 @@ SQLAlchemy supports Postgresql EXCLUDE constraints via the
 :class:`ExcludeConstraint` class:
 
 .. autoclass:: ExcludeConstraint
-   :show-inheritance:
    :members: __init__
 
 For example::
index cacbf570c56a8bb049ff04ea906bda42dc7300e6..bcba2d06741e8ee5d484363004de10a5af28b234 100644 (file)
@@ -74,11 +74,11 @@ are documented here.  In contrast to the ORM's domain-centric mode of usage, the
   :doc:`Connection Pooling <core/pooling>`
 
 * **Schema Definition:**
-  :ref:`Tables and Columns <metadata_describing>` |
-  :ref:`Database Introspection (Reflection) <metadata_reflection>` |
-  :ref:`Insert/Update Defaults <metadata_defaults>` |
-  :ref:`Constraints and Indexes <metadata_constraints>` |
-  :ref:`Using Data Definition Language (DDL) <metadata_ddl>`
+  :ref:`Tables and Columns <metadata_describing_toplevel>` |
+  :ref:`Database Introspection (Reflection) <metadata_reflection_toplevel>` |
+  :ref:`Insert/Update Defaults <metadata_defaults_toplevel>` |
+  :ref:`Constraints and Indexes <metadata_constraints_toplevel>` |
+  :ref:`Using Data Definition Language (DDL) <metadata_ddl_toplevel>`
 
 * **Datatypes:**
   :ref:`Overview <types_toplevel>` |
index 1dde4248fcba67df600f872a85df079b2625f7da..7a760e26fa20e04c8194958e155297e89e10bdc3 100644 (file)
@@ -2,5 +2,5 @@ ORM Exceptions
 ==============
 
 .. automodule:: sqlalchemy.orm.exc
-    :show-inheritance:
+     
     :members:
\ No newline at end of file
index 3ee76fd9bd819cb6f265e36315b2eb5422adf901..16cdafebcca42d859298ff60efbddbb23648cf8b 100644 (file)
@@ -15,7 +15,7 @@ API Reference
     :members:
 
 .. autoclass:: Comparator
-    :show-inheritance:
+     
 
 .. autodata:: HYBRID_METHOD
 
index 94946b1ae1b3e414f0cf37e6d8e33b79fc89c995..2337c39fddf5acbb680fc24cbabe255e63c22c2f 100644 (file)
@@ -17,7 +17,7 @@ API Reference
 .. autodata:: instrumentation_finders
 
 .. autoclass:: ExtendedInstrumentationRegistry
-    :show-inheritance:
+     
     :members:
 
 
index ba3e10542d22a4b3c638339d8307d1e851aa4c24..4b217ca4d767d12d2e46d57799392755b6b0027e 100644 (file)
@@ -12,15 +12,15 @@ API Reference
     :members: _parents, coerce
 
 .. autoclass:: Mutable
-    :show-inheritance:
+     
     :members:
 
 .. autoclass:: MutableComposite
-    :show-inheritance:
+     
     :members:
 
 .. autoclass:: MutableDict
-       :show-inheritance:
+        
        :members:
 
 
index 38efdb08ad72111e47d1df5c80e5b460f86d4e32..f8c9dd3435609619b238da396efd2362b6639307 100644 (file)
@@ -10,62 +10,62 @@ sections, are listed here.
 
 .. autoclass:: sqlalchemy.orm.state.AttributeState
     :members:
-    :show-inheritance:
+
     :inherited-members:
 
 .. autoclass:: sqlalchemy.orm.instrumentation.ClassManager
     :members:
-    :show-inheritance:
+
     :inherited-members:
 
 .. autoclass:: sqlalchemy.orm.properties.ColumnProperty
     :members:
-    :show-inheritance:
+
     :inherited-members:
 
 .. autoclass:: sqlalchemy.orm.descriptor_props.CompositeProperty
     :members:
-    :show-inheritance:
+
 
 .. autoclass:: sqlalchemy.orm.interfaces._InspectionAttr
     :members:
-    :show-inheritance:
+
 
 .. autoclass:: sqlalchemy.orm.state.InstanceState
     :members:
-    :show-inheritance:
+
 
 .. autoclass:: sqlalchemy.orm.attributes.InstrumentedAttribute
     :members: __get__, __set__, __delete__
-    :show-inheritance:
+
     :undoc-members:
 
 .. autoclass:: sqlalchemy.orm.interfaces.MapperProperty
     :members:
-    :show-inheritance:
+
 
 .. autodata:: sqlalchemy.orm.interfaces.NOT_EXTENSION
 
 .. autoclass:: sqlalchemy.orm.interfaces.PropComparator
     :members:
-    :show-inheritance:
+
     :inherited-members:
 
 .. autoclass:: sqlalchemy.orm.properties.RelationshipProperty
     :members:
-    :show-inheritance:
+
     :inherited-members:
 
 .. autoclass:: sqlalchemy.orm.descriptor_props.SynonymProperty
     :members:
-    :show-inheritance:
+
     :inherited-members:
 
 .. autoclass:: sqlalchemy.orm.query.QueryContext
     :members:
-    :show-inheritance:
+
 
 .. autoclass:: sqlalchemy.orm.attributes.QueryableAttribute
     :members:
-    :show-inheritance:
+
     :inherited-members:
index a81234c25c2a9ab099161ebadefa2b5ded57e709..f5470e87b4353c0bdc49468246ed13152a2400ea 100644 (file)
@@ -2048,12 +2048,10 @@ Session and sessionmaker()
 
 .. autoclass:: sessionmaker
     :members:
-    :show-inheritance:
     :inherited-members:
 
 .. autoclass:: sqlalchemy.orm.session.Session
    :members:
-   :show-inheritance:
    :inherited-members:
 
 .. autoclass:: sqlalchemy.orm.session.SessionTransaction
index 4d3dc08d04ed6984dde54ded209689d042f59aa2..b9862058c3d69bc9a0f32b9b45f9c208ba714b25 100644 (file)
@@ -133,3 +133,4 @@ print session.query(Company).\
 
 session.commit()
 
+