Author: fijal
Branch:
Changeset: r346:947a8b49e3cd
Date: 2016-01-20 22:31 +0100
http://bitbucket.org/pypy/benchmarks/changeset/947a8b49e3cd/
Log: add some other pyston benchmarks
diff too long, truncating to 2000 out of 513606 lines
diff --git a/benchmarks.py b/benchmarks.py
--- a/benchmarks.py
+++ b/benchmarks.py
@@ -66,6 +66,11 @@
'bm_dulwich_log': {'bm_env': {'PYTHONPATH':
relative('lib/dulwich-0.9.1')}},
'bm_chameleon': {'bm_env': {'PYTHONPATH': relative('lib/chameleon/src')},
'iteration_scaling': 3},
+ 'nqueens': {'iteration_scaling': .1},
+ 'sqlalchemy_declarative': {'bm_env': {'PYTHONPATH':
relative('lib/sqlalchemy/lib')},
+ 'iteration_scaling': 3},
+ 'sqlalchemy_imperative': {'bm_env': {'PYTHONPATH':
relative('lib/sqlalchemy/lib')},
+ 'iteration_scaling': 10},
}
for name in ['expand', 'integrate', 'sum', 'str']:
@@ -84,7 +89,8 @@
'raytrace-simple', 'crypto_pyaes', 'bm_mako', 'bm_chameleon',
'json_bench', 'pidigits', 'hexiom2', 'eparse', 'deltablue',
'bm_dulwich_log', 'bm_krakatau', 'bm_mdp', 'pypy_interp',
- 'sqlitesynth', 'pyxl_bench']:
+ 'sqlitesynth', 'pyxl_bench', 'nqueens', 'sqlalchemy_declarative',
+ 'sqlalchemy_imperative']:
_register_new_bm(name, name, globals(), **opts.get(name, {}))
for name in ['names', 'iteration', 'tcp', 'pb', ]:#'web']:#, 'accepts']:
diff --git a/lib/sqlalchemy/AUTHORS b/lib/sqlalchemy/AUTHORS
new file mode 100644
--- /dev/null
+++ b/lib/sqlalchemy/AUTHORS
@@ -0,0 +1,18 @@
+SQLAlchemy was created by Michael Bayer.
+
+Major contributing authors include:
+
+- Michael Bayer <[email protected]>
+- Jason Kirtland <[email protected]>
+- Gaetan de Menten <[email protected]>
+- Diana Clarke <[email protected]>
+- Michael Trier <[email protected]>
+- Philip Jenvey <[email protected]>
+- Ants Aasma <[email protected]>
+- Paul Johnston <[email protected]>
+- Jonathan Ellis <[email protected]>
+
+For a larger list of SQLAlchemy contributors over time, see:
+
+http://www.sqlalchemy.org/trac/wiki/Contributors
+
diff --git a/lib/sqlalchemy/CHANGES b/lib/sqlalchemy/CHANGES
new file mode 100644
--- /dev/null
+++ b/lib/sqlalchemy/CHANGES
@@ -0,0 +1,16 @@
+=====
+MOVED
+=====
+
+Please see:
+
+ /doc/changelog/index.html
+
+or
+
+ http://www.sqlalchemy.org/docs/latest/changelog/
+
+for an index of all changelogs.
+
+
+
diff --git a/lib/sqlalchemy/LICENSE b/lib/sqlalchemy/LICENSE
new file mode 100644
--- /dev/null
+++ b/lib/sqlalchemy/LICENSE
@@ -0,0 +1,20 @@
+This is the MIT license: http://www.opensource.org/licenses/mit-license.php
+
+Copyright (c) 2005-2015 the SQLAlchemy authors and contributors <see AUTHORS
file>.
+SQLAlchemy is a trademark of Michael Bayer.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
of this
+software and associated documentation files (the "Software"), to deal in the
Software
+without restriction, including without limitation the rights to use, copy,
modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons
+to whom the Software is furnished to do so, subject to the following
conditions:
+
+The above copyright notice and this permission notice shall be included in all
copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED,
+INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR
+PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE
+FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/lib/sqlalchemy/MANIFEST.in b/lib/sqlalchemy/MANIFEST.in
new file mode 100644
--- /dev/null
+++ b/lib/sqlalchemy/MANIFEST.in
@@ -0,0 +1,13 @@
+# any kind of "*" pulls in __init__.pyc files,
+# so all extensions are explicit.
+
+recursive-include doc *.html *.css *.txt *.js *.jpg *.png *.py Makefile *.rst
*.mako *.sty
+recursive-include examples *.py *.xml
+recursive-include test *.py *.dat
+
+# include the c extensions, which otherwise
+# don't come in if --with-cextensions isn't specified.
+recursive-include lib *.c *.txt
+
+include README* AUTHORS LICENSE distribute_setup.py sa2to3.py ez_setup.py
sqla_nose.py CHANGES* tox.ini
+prune doc/build/output
diff --git a/lib/sqlalchemy/PKG-INFO b/lib/sqlalchemy/PKG-INFO
new file mode 100644
--- /dev/null
+++ b/lib/sqlalchemy/PKG-INFO
@@ -0,0 +1,155 @@
+Metadata-Version: 1.1
+Name: SQLAlchemy
+Version: 1.0.11
+Summary: Database Abstraction Library
+Home-page: http://www.sqlalchemy.org
+Author: Mike Bayer
+Author-email: [email protected]
+License: MIT License
+Description: SQLAlchemy
+ ==========
+
+ The Python SQL Toolkit and Object Relational Mapper
+
+ Introduction
+ -------------
+
+ SQLAlchemy is the Python SQL toolkit and Object Relational Mapper
+ that gives application developers the full power and
+ flexibility of SQL. SQLAlchemy provides a full suite
+ of well known enterprise-level persistence patterns,
+ designed for efficient and high-performing database
+ access, adapted into a simple and Pythonic domain
+ language.
+
+ Major SQLAlchemy features include:
+
+ * An industrial strength ORM, built
+ from the core on the identity map, unit of work,
+ and data mapper patterns. These patterns
+ allow transparent persistence of objects
+ using a declarative configuration system.
+ Domain models
+ can be constructed and manipulated naturally,
+ and changes are synchronized with the
+ current transaction automatically.
+ * A relationally-oriented query system, exposing
+ the full range of SQL's capabilities
+ explicitly, including joins, subqueries,
+ correlation, and most everything else,
+ in terms of the object model.
+ Writing queries with the ORM uses the same
+ techniques of relational composition you use
+ when writing SQL. While you can drop into
+ literal SQL at any time, it's virtually never
+ needed.
+ * A comprehensive and flexible system
+ of eager loading for related collections and objects.
+ Collections are cached within a session,
+ and can be loaded on individual access, all
+ at once using joins, or by query per collection
+ across the full result set.
+ * A Core SQL construction system and DBAPI
+ interaction layer. The SQLAlchemy Core is
+ separate from the ORM and is a full database
+ abstraction layer in its own right, and includes
+ an extensible Python-based SQL expression
+ language, schema metadata, connection pooling,
+ type coercion, and custom types.
+ * All primary and foreign key constraints are
+ assumed to be composite and natural. Surrogate
+ integer primary keys are of course still the
+ norm, but SQLAlchemy never assumes or hardcodes
+ to this model.
+ * Database introspection and generation. Database
+ schemas can be "reflected" in one step into
+ Python structures representing database metadata;
+ those same structures can then generate
+ CREATE statements right back out - all within
+ the Core, independent of the ORM.
+
+ SQLAlchemy's philosophy:
+
+ * SQL databases behave less and less like object
+ collections the more size and performance start to
+ matter; object collections behave less and less like
+ tables and rows the more abstraction starts to matter.
+ SQLAlchemy aims to accommodate both of these
+ principles.
+ * An ORM doesn't need to hide the "R". A relational
+ database provides rich, set-based functionality
+ that should be fully exposed. SQLAlchemy's
+ ORM provides an open-ended set of patterns
+ that allow a developer to construct a custom
+ mediation layer between a domain model and
+ a relational schema, turning the so-called
+ "object relational impedance" issue into
+ a distant memory.
+ * The developer, in all cases, makes all decisions
+ regarding the design, structure, and naming conventions
+ of both the object model as well as the relational
+ schema. SQLAlchemy only provides the means
+ to automate the execution of these decisions.
+ * With SQLAlchemy, there's no such thing as
+ "the ORM generated a bad query" - you
+ retain full control over the structure of
+ queries, including how joins are organized,
+ how subqueries and correlation is used, what
+ columns are requested. Everything SQLAlchemy
+ does is ultimately the result of a developer-
+ initiated decision.
+ * Don't use an ORM if the problem doesn't need one.
+ SQLAlchemy consists of a Core and separate ORM
+ component. The Core offers a full SQL expression
+ language that allows Pythonic construction
+ of SQL constructs that render directly to SQL
+ strings for a target database, returning
+ result sets that are essentially enhanced DBAPI
+ cursors.
+ * Transactions should be the norm. With SQLAlchemy's
+ ORM, nothing goes to permanent storage until
+ commit() is called. SQLAlchemy encourages applications
+ to create a consistent means of delineating
+ the start and end of a series of operations.
+ * Never render a literal value in a SQL statement.
+ Bound parameters are used to the greatest degree
+ possible, allowing query optimizers to cache
+ query plans effectively and making SQL injection
+ attacks a non-issue.
+
+ Documentation
+ -------------
+
+ Latest documentation is at:
+
+ http://www.sqlalchemy.org/docs/
+
+ Installation / Requirements
+ ---------------------------
+
+ Full documentation for installation is at
+ `Installation
<http://www.sqlalchemy.org/docs/intro.html#installation>`_.
+
+ Getting Help / Development / Bug reporting
+ ------------------------------------------
+
+ Please refer to the `SQLAlchemy Community Guide
<http://www.sqlalchemy.org/support.html>`_.
+
+ License
+ -------
+
+ SQLAlchemy is distributed under the `MIT license
+ <http://www.opensource.org/licenses/mit-license.php>`_.
+
+
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Programming Language :: Python :: Implementation :: Jython
+Classifier: Programming Language :: Python :: Implementation :: PyPy
+Classifier: Topic :: Database :: Front-Ends
+Classifier: Operating System :: OS Independent
diff --git a/lib/sqlalchemy/README.dialects.rst
b/lib/sqlalchemy/README.dialects.rst
new file mode 100644
--- /dev/null
+++ b/lib/sqlalchemy/README.dialects.rst
@@ -0,0 +1,262 @@
+========================
+Developing new Dialects
+========================
+
+.. note::
+
+ When studying this file, it's probably a good idea to also
+ familiarize with the README.unittests.rst file, which discusses
+ SQLAlchemy's usage and extension of the Nose test runner.
+
+While SQLAlchemy includes many dialects within the core distribution, the
+trend for new dialects should be that they are published as external
+projects. SQLAlchemy has since version 0.5 featured a "plugin" system
+which allows external dialects to be integrated into SQLAlchemy using
+standard setuptools entry points. As of version 0.8, this system has
+been enhanced, so that a dialect can also be "plugged in" at runtime.
+
+On the testing side, SQLAlchemy as of 0.8 also includes a "dialect
+compliance suite" that is usable by third party libraries. There is no
+longer a strong need for a new dialect to run through SQLAlchemy's full
+testing suite, as a large portion of these tests do not have
+dialect-sensitive functionality. The "dialect compliance suite" should
+be viewed as the primary target for new dialects, and as it continues
+to grow and mature it should become a more thorough and efficient system
+of testing new dialects.
+
+As of SQLAlchemy 0.9.4, both nose and pytest are supported for running tests,
+and pytest is now preferred.
+
+Dialect Layout
+===============
+
+The file structure of a dialect is typically similar to the following::
+
+ sqlalchemy-<dialect>/
+ setup.py
+ setup.cfg
+ run_tests.py
+ sqlalchemy_<dialect>/
+ __init__.py
+ base.py
+ <dbapi>.py
+ requirements.py
+ test/
+ conftest.py
+ __init__.py
+ test_suite.py
+ test_<dialect_specific_test>.py
+ ...
+
+An example of this structure can be seen in the Access dialect at
+https://bitbucket.org/zzzeek/sqlalchemy-access/.
+
+Key aspects of this file layout include:
+
+* setup.py - should specify setuptools entrypoints, allowing the
+ dialect to be usable from create_engine(), e.g.::
+
+ entry_points={
+ 'sqlalchemy.dialects': [
+ 'access = sqlalchemy_access.pyodbc:AccessDialect_pyodbc',
+ 'access.pyodbc = sqlalchemy_access.pyodbc:AccessDialect_pyodbc',
+ ]
+ }
+
+ Above, the two entrypoints ``access`` and ``access.pyodbc`` allow URLs to be
+ used such as::
+
+ create_engine("access://user:pw@dsn")
+
+ create_engine("access+pyodbc://user:pw@dsn")
+
+* setup.cfg - this file contains the traditional contents such as [egg_info],
+ [pytest] and [nosetests] directives, but also contains new directives that
are used
+ by SQLAlchemy's testing framework. E.g. for Access::
+
+ [egg_info]
+ tag_build = dev
+
+ [pytest]
+ addopts= --tb native -v -r fxX
+ python_files=test/*test_*.py
+
+ [nosetests]
+ with-sqla_testing = true
+ where = test
+ cover-package = sqlalchemy_access
+ with-coverage = 1
+ cover-erase = 1
+
+ [sqla_testing]
+ requirement_cls=sqlalchemy_access.requirements:Requirements
+ profile_file=.profiles.txt
+
+ [db]
+ default=access+pyodbc://admin@access_test
+ sqlite=sqlite:///:memory:
+
+ Above, the ``[sqla_testing]`` section contains configuration used by
+ SQLAlchemy's test plugin. The ``[pytest]`` and ``[nosetests]`` sections
+ include directives to help with these runners; in the case of
+ Nose, the directive ``with-sql_testing = true``, which indicates to Nose that
+ the SQLAlchemy nose plugin should be used. In the case of pytest, the
+ test/conftest.py file will bootstrap SQLAlchemy's plugin.
+
+* test/conftest.py - This script bootstraps SQLAlchemy's pytest plugin
+ into the pytest runner. This
+ script can also be used to install your third party dialect into
+ SQLAlchemy without using the setuptools entrypoint system; this allows
+ your dialect to be present without any explicit setup.py step needed.
+ The other portion invokes SQLAlchemy's pytest plugin::
+
+ from sqlalchemy.dialects import registry
+
+ registry.register("access", "sqlalchemy_access.pyodbc",
"AccessDialect_pyodbc")
+ registry.register("access.pyodbc", "sqlalchemy_access.pyodbc",
"AccessDialect_pyodbc")
+
+ from sqlalchemy.testing.plugin.pytestplugin import *
+
+ Where above, the ``registry`` module, introduced in SQLAlchemy 0.8, provides
+ an in-Python means of installing the dialect entrypoints without the use
+ of setuptools, using the ``registry.register()`` function in a way that
+ is similar to the ``entry_points`` directive we placed in our ``setup.py``.
+
+* run_tests.py - This script is used when running the tests via Nose.
+ The purpose of the script is to plug in SQLAlchemy's nose plugin into
+ the Nose environment before the tests run.
+
+ The format of this file is similar to that of conftest.py; first,
+ the optional but helpful step of registering your third party plugin,
+ then the other is to import SQLAlchemy's nose runner and invoke it::
+
+ from sqlalchemy.dialects import registry
+
+ registry.register("access", "sqlalchemy_access.pyodbc",
"AccessDialect_pyodbc")
+ registry.register("access.pyodbc", "sqlalchemy_access.pyodbc",
"AccessDialect_pyodbc")
+
+ from sqlalchemy.testing import runner
+
+ # use this in setup.py 'test_suite':
+ # test_suite="run_tests.setup_py_test"
+ def setup_py_test():
+ runner.setup_py_test()
+
+ if __name__ == '__main__':
+ runner.main()
+
+ The call to ``runner.main()`` then runs the Nose front end, which installs
+ SQLAlchemy's testing plugins. Invoking our custom runner looks like the
+ following::
+
+ $ python run_tests.py -v
+
+* requirements.py - The ``requirements.py`` file is where directives
+ regarding database and dialect capabilities are set up.
+ SQLAlchemy's tests are often annotated with decorators that mark
+ tests as "skip" or "fail" for particular backends. Over time, this
+ system has been refined such that specific database and DBAPI names
+ are mentioned less and less, in favor of @requires directives which
+ state a particular capability. The requirement directive is linked
+ to target dialects using a ``Requirements`` subclass. The custom
+ ``Requirements`` subclass is specified in the ``requirements.py`` file
+ and is made available to SQLAlchemy's test runner using the
+ ``requirement_cls`` directive inside the ``[sqla_testing]`` section.
+
+ For a third-party dialect, the custom ``Requirements`` class can
+ usually specify a simple yes/no answer for a particular system. For
+ example, a requirements file that specifies a database that supports
+ the RETURNING construct but does not support reflection of tables
+ might look like this::
+
+ # sqlalchemy_access/requirements.py
+
+ from sqlalchemy.testing.requirements import SuiteRequirements
+
+ from sqlalchemy.testing import exclusions
+
+ class Requirements(SuiteRequirements):
+ @property
+ def table_reflection(self):
+ return exclusions.closed()
+
+ @property
+ def returning(self):
+ return exclusions.open()
+
+ The ``SuiteRequirements`` class in
+ ``sqlalchemy.testing.requirements`` contains a large number of
+ requirements rules, which attempt to have reasonable defaults. The
+ tests will report on those requirements found as they are run.
+
+ The requirements system can also be used when running SQLAlchemy's
+ primary test suite against the external dialect. In this use case,
+ a ``--dburi`` as well as a ``--requirements`` flag are passed to SQLAlchemy's
+ main test runner ``./sqla_nose.py`` so that exclusions specific to the
+ dialect take place::
+
+ cd /path/to/sqlalchemy
+ py.test -v \
+ --requirements sqlalchemy_access.requirements:Requirements \
+ --dburi access+pyodbc://admin@access_test
+
+* test_suite.py - Finally, the ``test_suite.py`` module represents a
+ stub test suite, which pulls in the actual SQLAlchemy test suite.
+ To pull in the suite as a whole, it can be imported in one step::
+
+ # test/test_suite.py
+
+ from sqlalchemy.testing.suite import *
+
+ That's all that's needed - the ``sqlalchemy.testing.suite`` package
+ contains an ever expanding series of tests, most of which should be
+ annotated with specific requirement decorators so that they can be
+ fully controlled. To specifically modify some of the tests, they can
+ be imported by name and subclassed::
+
+ from sqlalchemy.testing.suite import *
+
+ from sqlalchemy.testing.suite import ComponentReflectionTest as
_ComponentReflectionTest
+
+ class ComponentReflectionTest(_ComponentReflectionTest):
+ @classmethod
+ def define_views(cls, metadata, schema):
+ # bypass the "define_views" section of the
+ # fixture
+ return
+
+Going Forward
+==============
+
+The third-party dialect can be distributed like any other Python
+module on Pypi. Links to prominent dialects can be featured within
+SQLAlchemy's own documentation; contact the developers (see AUTHORS)
+for help with this.
+
+While SQLAlchemy includes many dialects built in, it remains to be
+seen if the project as a whole might move towards "plugin" model for
+all dialects, including all those currently built in. Now that
+SQLAlchemy's dialect API is mature and the test suite is not far
+behind, it may be that a better maintenance experience can be
+delivered by having all dialects separately maintained and released.
+
+As new versions of SQLAlchemy are released, the test suite and
+requirements file will receive new tests and changes. The dialect
+maintainer would normally keep track of these changes and make
+adjustments as needed.
+
+Continuous Integration
+======================
+
+The most ideal scenario for ongoing dialect testing is continuous
+integration, that is, an automated test runner that runs in response
+to changes not just in the dialect itself but to new pushes to
+SQLAlchemy as well.
+
+The SQLAlchemy project features a Jenkins installation that runs tests
+on Amazon EC2 instances. It is possible for third-party dialect
+developers to provide the SQLAlchemy project either with AMIs or EC2
+instance keys which feature test environments appropriate to the
+dialect - SQLAlchemy's own Jenkins suite can invoke tests on these
+environments. Contact the developers for further info.
+
diff --git a/lib/sqlalchemy/README.rst b/lib/sqlalchemy/README.rst
new file mode 100644
--- /dev/null
+++ b/lib/sqlalchemy/README.rst
@@ -0,0 +1,135 @@
+SQLAlchemy
+==========
+
+The Python SQL Toolkit and Object Relational Mapper
+
+Introduction
+-------------
+
+SQLAlchemy is the Python SQL toolkit and Object Relational Mapper
+that gives application developers the full power and
+flexibility of SQL. SQLAlchemy provides a full suite
+of well known enterprise-level persistence patterns,
+designed for efficient and high-performing database
+access, adapted into a simple and Pythonic domain
+language.
+
+Major SQLAlchemy features include:
+
+* An industrial strength ORM, built
+ from the core on the identity map, unit of work,
+ and data mapper patterns. These patterns
+ allow transparent persistence of objects
+ using a declarative configuration system.
+ Domain models
+ can be constructed and manipulated naturally,
+ and changes are synchronized with the
+ current transaction automatically.
+* A relationally-oriented query system, exposing
+ the full range of SQL's capabilities
+ explicitly, including joins, subqueries,
+ correlation, and most everything else,
+ in terms of the object model.
+ Writing queries with the ORM uses the same
+ techniques of relational composition you use
+ when writing SQL. While you can drop into
+ literal SQL at any time, it's virtually never
+ needed.
+* A comprehensive and flexible system
+ of eager loading for related collections and objects.
+ Collections are cached within a session,
+ and can be loaded on individual access, all
+ at once using joins, or by query per collection
+ across the full result set.
+* A Core SQL construction system and DBAPI
+ interaction layer. The SQLAlchemy Core is
+ separate from the ORM and is a full database
+ abstraction layer in its own right, and includes
+ an extensible Python-based SQL expression
+ language, schema metadata, connection pooling,
+ type coercion, and custom types.
+* All primary and foreign key constraints are
+ assumed to be composite and natural. Surrogate
+ integer primary keys are of course still the
+ norm, but SQLAlchemy never assumes or hardcodes
+ to this model.
+* Database introspection and generation. Database
+ schemas can be "reflected" in one step into
+ Python structures representing database metadata;
+ those same structures can then generate
+ CREATE statements right back out - all within
+ the Core, independent of the ORM.
+
+SQLAlchemy's philosophy:
+
+* SQL databases behave less and less like object
+ collections the more size and performance start to
+ matter; object collections behave less and less like
+ tables and rows the more abstraction starts to matter.
+ SQLAlchemy aims to accommodate both of these
+ principles.
+* An ORM doesn't need to hide the "R". A relational
+ database provides rich, set-based functionality
+ that should be fully exposed. SQLAlchemy's
+ ORM provides an open-ended set of patterns
+ that allow a developer to construct a custom
+ mediation layer between a domain model and
+ a relational schema, turning the so-called
+ "object relational impedance" issue into
+ a distant memory.
+* The developer, in all cases, makes all decisions
+ regarding the design, structure, and naming conventions
+ of both the object model as well as the relational
+ schema. SQLAlchemy only provides the means
+ to automate the execution of these decisions.
+* With SQLAlchemy, there's no such thing as
+ "the ORM generated a bad query" - you
+ retain full control over the structure of
+ queries, including how joins are organized,
+ how subqueries and correlation is used, what
+ columns are requested. Everything SQLAlchemy
+ does is ultimately the result of a developer-
+ initiated decision.
+* Don't use an ORM if the problem doesn't need one.
+ SQLAlchemy consists of a Core and separate ORM
+ component. The Core offers a full SQL expression
+ language that allows Pythonic construction
+ of SQL constructs that render directly to SQL
+ strings for a target database, returning
+ result sets that are essentially enhanced DBAPI
+ cursors.
+* Transactions should be the norm. With SQLAlchemy's
+ ORM, nothing goes to permanent storage until
+ commit() is called. SQLAlchemy encourages applications
+ to create a consistent means of delineating
+ the start and end of a series of operations.
+* Never render a literal value in a SQL statement.
+ Bound parameters are used to the greatest degree
+ possible, allowing query optimizers to cache
+ query plans effectively and making SQL injection
+ attacks a non-issue.
+
+Documentation
+-------------
+
+Latest documentation is at:
+
+http://www.sqlalchemy.org/docs/
+
+Installation / Requirements
+---------------------------
+
+Full documentation for installation is at
+`Installation <http://www.sqlalchemy.org/docs/intro.html#installation>`_.
+
+Getting Help / Development / Bug reporting
+------------------------------------------
+
+Please refer to the `SQLAlchemy Community Guide
<http://www.sqlalchemy.org/support.html>`_.
+
+License
+-------
+
+SQLAlchemy is distributed under the `MIT license
+<http://www.opensource.org/licenses/mit-license.php>`_.
+
diff --git a/lib/sqlalchemy/README.unittests.rst
b/lib/sqlalchemy/README.unittests.rst
new file mode 100644
--- /dev/null
+++ b/lib/sqlalchemy/README.unittests.rst
@@ -0,0 +1,340 @@
+=====================
+SQLALCHEMY UNIT TESTS
+=====================
+
+**NOTE:** SQLAlchemy as of 0.9.4 now standardizes on `pytest
<http://pytest.org/>`_
+for test running! However, the existing support for Nose **still remains**!
+That is, you can now run the tests via pytest or nose. We hope to keep the
+suite nose-compatible indefinitely however this might change at some point.
+
+SQLAlchemy unit tests by default run using Python's built-in sqlite3
+module. If running on a Python installation that doesn't include this
+module, then pysqlite or compatible must be installed.
+
+Unit tests can be run with pytest or nose:
+
+ py.test: http://pytest.org/
+
+ nose: https://pypi.python.org/pypi/nose/
+
+The suite includes enhanced support when running with pytest.
+
+SQLAlchemy implements plugins for both pytest and nose that must be
+present when tests are run. In the case of pytest, this plugin is
automatically
+used when pytest is run against the SQLAlchemy source tree. However,
+for Nose support, a special test runner script must be used.
+
+
+The test suite as also requires the mock library. While
+mock is part of the Python standard library as of 3.3, previous versions
+will need to have it installed, and is available at::
+
+ https://pypi.python.org/pypi/mock
+
+RUNNING TESTS VIA SETUP.PY
+--------------------------
+A plain vanilla run of all tests using sqlite can be run via setup.py, and
+requires that pytest is installed::
+
+ $ python setup.py test
+
+
+RUNNING ALL TESTS - PYTEST
+--------------------------
+To run all tests::
+
+ $ py.test
+
+The pytest configuration in setup.cfg will point the runner at the
+test/ directory, where it consumes a conftest.py file that gets everything
+else up and running.
+
+
+RUNNING ALL TESTS - NOSE
+--------------------------
+
+When using Nose, a bootstrap script is provided which sets up sys.path
+as well as installs the nose plugin::
+
+ $ ./sqla_nose.py
+
+Assuming all tests pass, this is a very unexciting output. To make it more
+interesting::
+
+ $ ./sqla_nose.py -v
+
+RUNNING INDIVIDUAL TESTS
+---------------------------------
+
+Any directory of test modules can be run at once by specifying the directory
+path, and a specific file can be specified as well::
+
+ $ py.test test/dialect
+
+ $ py.test test/orm/test_mapper.py
+
+When using nose, the setup.cfg currently sets "where" to "test/", so the
+"test/" prefix is omitted::
+
+ $ ./sqla_nose.py dialect/
+
+ $ ./sqla_nose.py orm/test_mapper.py
+
+With Nose, it is often more intuitive to specify tests as module paths::
+
+ $ ./sqla_nose.py test.orm.test_mapper
+
+Nose can also specify a test class and optional method using this syntax::
+
+ $ ./sqla_nose.py test.orm.test_mapper:MapperTest.test_utils
+
+With pytest, the -k flag is used to limit tests::
+
+ $ py.test test/orm/test_mapper.py -k "MapperTest and test_utils"
+
+
+COMMAND LINE OPTIONS
+--------------------
+
+SQLAlchemy-specific options are added to both runners, which are viewable
+within the help screen. With pytest, these options are easier to locate
+as they are underneath the "sqlalchemy" grouping::
+
+ $ py.test --help
+
+ $ ./sqla_nose.py --help
+
+The --help screen is a combination of common nose options and options which
+the SQLAlchemy nose plugin adds. The most commonly SQLAlchemy-specific
+options used are '--db' and '--dburi'.
+
+Both pytest and nose support the same set of SQLAlchemy options, though
+pytest features a bit more capability with them.
+
+
+DATABASE TARGETS
+----------------
+
+Tests will target an in-memory SQLite database by default. To test against
+another database, use the --dburi option with any standard SQLAlchemy URL::
+
+ --dburi=postgresql://user:password@localhost/test
+
+If you'll be running the tests frequently, database aliases can save a lot of
+typing. The --dbs option lists the built-in aliases and their matching URLs::
+
+ $ py.test --dbs
+ Available --db options (use --dburi to override)
+ mysql mysql://scott:[email protected]:3306/test
+ oracle oracle://scott:[email protected]:1521
+ postgresql postgresql://scott:[email protected]:5432/test
+ [...]
+
+To run tests against an aliased database::
+
+ $ py.test --db postgresql
+
+This list of database urls is present in the setup.cfg file. The list
+can be modified/extended by adding a file ``test.cfg`` at the
+top level of the SQLAlchemy source distribution which includes
+additional entries::
+
+ [db]
+ postgresql=postgresql://myuser:mypass@localhost/mydb
+
+Your custom entries will override the defaults and you'll see them reflected
+in the output of --dbs.
+
+MULTIPLE DATABASE TARGETS
+-------------------------
+
+As of SQLAlchemy 0.9.4, the test runner supports **multiple databases at
once**.
+This doesn't mean that the entire test suite runs for each database, but
+instead specific test suites may do so, while other tests may choose to
+run on a specific target out of those available. For example, if the tests
underneath
+test/dialect/ are run, the majority of these tests are either specific to
+a particular backend, or are marked as "multiple", meaning they will run
repeatedly
+for each database in use. If one runs the test suite as follows::
+
+ $ py.test test/dialect --db sqlite --db postgresql --db mysql
+
+The tests underneath test/dialect/test_suite.py will be tripled up, running
+as appropriate for each target database, whereas dialect-specific tests
+within test/dialect/mysql, test/dialect/postgresql/ test/dialect/test_sqlite.py
+should run fully with no skips, as each suite has its target database
available.
+
+The multiple targets feature is available both under pytest and nose,
+however when running nose, the "multiple runner" feature won't be available;
+instead, the first database target will be used.
+
+When running with multiple targets, tests that don't prefer a specific target
+will be run against the first target specified. Putting sqlite first in
+the list will lead to a much faster suite as the in-memory database is
+extremely fast for setting up and tearing down tables.
+
+
+
+DATABASE CONFIGURATION
+----------------------
+
+Use an empty database and a database user with general DBA privileges.
+The test suite will be creating and dropping many tables and other DDL, and
+preexisting tables will interfere with the tests.
+
+Several tests require alternate usernames or schemas to be present, which
+are used to test dotted-name access scenarios. On some databases such
+as Oracle or Sybase, these are usernames, and others such as Postgresql
+and MySQL they are schemas. The requirement applies to all backends
+except SQLite and Firebird. The names are::
+
+ test_schema
+ test_schema_2 (only used on Postgresql)
+
+Please refer to your vendor documentation for the proper syntax to create
+these namespaces - the database user must have permission to create and drop
+tables within these schemas. Its perfectly fine to run the test suite
+without these namespaces present, it only means that a handful of tests which
+expect them to be present will fail.
+
+Additional steps specific to individual databases are as follows::
+
+ POSTGRESQL: To enable unicode testing with JSONB, create the
+ database with UTF8 encoding::
+
+ postgres=# create database test with owner=scott encoding='utf8'
template=template0;
+
+ To include tests for HSTORE, create the HSTORE type engine::
+
+ postgres=# \c test;
+ You are now connected to database "test" as user "postgresql".
+ test=# create extension hstore;
+ CREATE EXTENSION
+
+ MYSQL: Default storage engine should be "MyISAM". Tests that require
+ "InnoDB" as the engine will specify this explicitly.
+
+ ORACLE: a user named "test_schema" is created.
+
+ The primary database user needs to be able to create and drop tables,
+ synonyms, and constraints within the "test_schema" user. For this
+ to work fully, including that the user has the "REFERENCES" role
+ in a remote schema for tables not yet defined (REFERENCES is per-table),
+ it is required that the test the user be present in the "DBA" role:
+
+ grant dba to scott;
+
+ SYBASE: Similar to Oracle, "test_schema" is created as a user, and the
+ primary test user needs to have the "sa_role".
+
+ It's also recommended to turn on "trunc log on chkpt" and to use a
+ separate transaction log device - Sybase basically seizes up when
+ the transaction log is full otherwise.
+
+ A full series of setup assuming sa/master:
+
+ disk init name="translog", physname="/opt/sybase/data/translog.dat",
size="10M"
+ create database sqlalchemy on default log on translog="10M"
+ sp_dboption sqlalchemy, "trunc log on chkpt", true
+ sp_addlogin scott, "tiger7"
+ sp_addlogin test_schema, "tiger7"
+ use sqlalchemy
+ sp_adduser scott
+ sp_adduser test_schema
+ grant all to scott
+ sp_role "grant", sa_role, scott
+
+ Sybase will still freeze for up to a minute when the log becomes
+ full. To manually dump the log::
+
+ dump tran sqlalchemy with truncate_only
+
+ MSSQL: Tests that involve multiple connections require Snapshot Isolation
+ ability implemented on the test database in order to prevent deadlocks that
+ will occur with record locking isolation. This feature is only available
+ with MSSQL 2005 and greater. You must enable snapshot isolation at the
+ database level and set the default cursor isolation with two SQL commands:
+
+ ALTER DATABASE MyDatabase SET ALLOW_SNAPSHOT_ISOLATION ON
+
+ ALTER DATABASE MyDatabase SET READ_COMMITTED_SNAPSHOT ON
+
+ MSSQL+zxJDBC: Trying to run the unit tests on Windows against SQL Server
+ requires using a test.cfg configuration file as the cmd.exe shell won't
+ properly pass the URL arguments into the nose test runner.
+
+ POSTGRESQL: Full-text search configuration should be set to English, else
+ several tests of ``.match()`` will fail. This can be set (if it isn't so
+ already) with:
+
+ ALTER DATABASE test SET default_text_search_config = 'pg_catalog.english'
+
+
+CONFIGURING LOGGING
+-------------------
+SQLAlchemy logs its activity and debugging through Python's logging package.
+Any log target can be directed to the console with command line options, such
+as::
+
+ $ ./sqla_nose.py test.orm.unitofwork --log-info=sqlalchemy.orm.mapper \
+ --log-debug=sqlalchemy.pool --log-info=sqlalchemy.engine
+
+This would log mapper configuration, connection pool checkouts, and SQL
+statement execution.
+
+
+BUILT-IN COVERAGE REPORTING
+------------------------------
+Coverage is tracked using the coverage plugins built for pytest or nose::
+
+ $ py.test test/sql/test_query --cov=sqlalchemy
+
+ $ ./sqla_nose.py test.sql.test_query --with-coverage
+
+BIG COVERAGE TIP !!! There is an issue where existing .pyc files may
+store the incorrect filepaths, which will break the coverage system. If
+coverage numbers are coming out as low/zero, try deleting all .pyc files.
+
+DEVELOPING AND TESTING NEW DIALECTS
+-----------------------------------
+
+See the file README.dialects.rst for detail on dialects.
+
+
+TESTING WITH MULTIPLE PYTHON VERSIONS USING TOX
+-----------------------------------------------
+
+If you want to test across multiple versions of Python, you may find `tox
+<http://tox.testrun.org/>`_ useful. SQLAlchemy includes a tox.ini file::
+
+ tox -e full
+
+SQLAlchemy uses tox mostly for pre-fab testing configurations, to simplify
+configuration of Jenkins jobs, and *not* for testing different Python
+interpreters simultaneously. You can of course create whatever alternate
+tox.ini file you want.
+
+Environments include::
+
+ "full" - runs a full py.test
+
+ "coverage" - runs a py.test plus coverage, skipping memory/timing
+ intensive tests
+
+ "pep8" - runs flake8 against the codebase (useful with --diff to check
+ against a patch)
+
+
+PARALLEL TESTING
+----------------
+
+Parallel testing is supported using the Pytest xdist plugin. Supported
+databases currently include sqlite, postgresql, and mysql. The username
+for the database should have CREATE DATABASE and DROP DATABASE privileges.
+After installing pytest-xdist, testing is run adding the -n<num> option.
+For example, to run against sqlite, mysql, postgresql with four processes::
+
+ tox -e -- -n 4 --db sqlite --db postgresql --db mysql
+
+Each backend has a different scheme for setting up the database. Postgresql
+still needs the "test_schema" and "test_schema_2" schemas present, as the
+parallel databases are created using the base database as a "template".
diff --git a/lib/sqlalchemy/doc/_images/sqla_arch_small.png
b/lib/sqlalchemy/doc/_images/sqla_arch_small.png
new file mode 100644
index
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..a1c09585ec8d45ee60ad356b315d5a4089421068
GIT binary patch
[cut]
diff --git a/lib/sqlalchemy/doc/_images/sqla_engine_arch.png
b/lib/sqlalchemy/doc/_images/sqla_engine_arch.png
new file mode 100644
index
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..f040a2cf317c0118bc9d5b12c458224dea4eb690
GIT binary patch
[cut]
diff --git
a/lib/sqlalchemy/doc/_modules/examples/adjacency_list/adjacency_list.html
b/lib/sqlalchemy/doc/_modules/examples/adjacency_list/adjacency_list.html
new file mode 100644
--- /dev/null
+++ b/lib/sqlalchemy/doc/_modules/examples/adjacency_list/adjacency_list.html
@@ -0,0 +1,253 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>
+
+
+ examples.adjacency_list.adjacency_list
+ —
+ SQLAlchemy 1.0 Documentation
+
+ </title>
+
+
+ <!-- begin iterate through SQLA + sphinx environment css_files -->
+ <link rel="stylesheet" href="../../../_static/pygments.css"
type="text/css" />
+ <link rel="stylesheet" href="../../../_static/changelog.css"
type="text/css" />
+ <link rel="stylesheet"
href="../../../_static/sphinx_paramlinks.css" type="text/css" />
+ <link rel="stylesheet" href="../../../_static/docs.css"
type="text/css" />
+ <!-- end iterate through SQLA + sphinx environment css_files -->
+
+
+
+
+
+
+ <!-- begin layout.mako headers -->
+
+ <link rel="index" title="Index" href="../../../genindex.html" />
+ <link rel="search" title="Search" href="../../../search.html" />
+ <link rel="copyright" title="Copyright" href="../../../copyright.html"
/>
+ <link rel="top" title="SQLAlchemy 1.0 Documentation"
href="../../../index.html" />
+ <link rel="up" title="Module code" href="../../index.html" />
+ <!-- end layout.mako headers -->
+
+
+ </head>
+ <body>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<div id="docs-container">
+
+
+
+
+
+<div id="docs-top-navigation-container" class="body-background">
+<div id="docs-header">
+ <div id="docs-version-header">
+ Release: <span class="version-num">1.0.11</span> | Release Date:
December 12, 2015
+ </div>
+
+ <h1>SQLAlchemy 1.0 Documentation</h1>
+
+</div>
+</div>
+
+<div id="docs-body-container">
+
+ <div id="fixed-sidebar" class="">
+
+ <div id="index-nav">
+ <form class="search" action="../../../search.html" method="get">
+ <input type="text" name="q" size="12" /> <input type="submit"
value="Search" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+
+ <p>
+ <a href="../../../contents.html">Contents</a> |
+ <a href="../../../genindex.html">Index</a>
+ </p>
+
+ </div>
+
+
+ </div>
+
+
+
+ <div id="docs-body" class="" >
+
+<h1>Source code for examples.adjacency_list.adjacency_list</h1><div
class="highlight"><pre>
+<span class="kn">from</span> <span class="nn">sqlalchemy</span> <span
class="kn">import</span> <span class="n">Column</span><span class="p">,</span>
<span class="n">ForeignKey</span><span class="p">,</span> <span
class="n">Integer</span><span class="p">,</span> <span
class="n">String</span><span class="p">,</span> <span
class="n">create_engine</span>
+<span class="kn">from</span> <span class="nn">sqlalchemy.orm</span> <span
class="kn">import</span> <span class="n">Session</span><span class="p">,</span>
<span class="n">relationship</span><span class="p">,</span> <span
class="n">backref</span><span class="p">,</span>\
+ <span class="n">joinedload_all</span>
+<span class="kn">from</span> <span
class="nn">sqlalchemy.ext.declarative</span> <span class="kn">import</span>
<span class="n">declarative_base</span>
+<span class="kn">from</span> <span
class="nn">sqlalchemy.orm.collections</span> <span class="kn">import</span>
<span class="n">attribute_mapped_collection</span>
+
+
+<span class="n">Base</span> <span class="o">=</span> <span
class="n">declarative_base</span><span class="p">()</span>
+
+<span class="k">class</span> <span class="nc">TreeNode</span><span
class="p">(</span><span class="n">Base</span><span class="p">):</span>
+ <span class="n">__tablename__</span> <span class="o">=</span> <span
class="s">'tree'</span>
+ <span class="nb">id</span> <span class="o">=</span> <span
class="n">Column</span><span class="p">(</span><span
class="n">Integer</span><span class="p">,</span> <span
class="n">primary_key</span><span class="o">=</span><span
class="bp">True</span><span class="p">)</span>
+ <span class="n">parent_id</span> <span class="o">=</span> <span
class="n">Column</span><span class="p">(</span><span
class="n">Integer</span><span class="p">,</span> <span
class="n">ForeignKey</span><span class="p">(</span><span
class="nb">id</span><span class="p">))</span>
+ <span class="n">name</span> <span class="o">=</span> <span
class="n">Column</span><span class="p">(</span><span
class="n">String</span><span class="p">(</span><span class="mi">50</span><span
class="p">),</span> <span class="n">nullable</span><span
class="o">=</span><span class="bp">False</span><span class="p">)</span>
+
+ <span class="n">children</span> <span class="o">=</span> <span
class="n">relationship</span><span class="p">(</span><span
class="s">"TreeNode"</span><span class="p">,</span>
+
+ <span class="c"># cascade deletions</span>
+ <span class="n">cascade</span><span
class="o">=</span><span class="s">"all, delete-orphan"</span><span
class="p">,</span>
+
+ <span class="c"># many to one + adjacency list -
remote_side</span>
+ <span class="c"># is required to reference the
'remote'</span>
+ <span class="c"># column in the join condition.</span>
+ <span class="n">backref</span><span
class="o">=</span><span class="n">backref</span><span class="p">(</span><span
class="s">"parent"</span><span class="p">,</span> <span
class="n">remote_side</span><span class="o">=</span><span
class="nb">id</span><span class="p">),</span>
+
+ <span class="c"># children will be represented as a
dictionary</span>
+ <span class="c"># on the "name"
attribute.</span>
+ <span class="n">collection_class</span><span
class="o">=</span><span class="n">attribute_mapped_collection</span><span
class="p">(</span><span class="s">'name'</span><span class="p">),</span>
+ <span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span
class="n">name</span><span class="p">,</span> <span
class="n">parent</span><span class="o">=</span><span
class="bp">None</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span
class="n">name</span> <span class="o">=</span> <span class="n">name</span>
+ <span class="bp">self</span><span class="o">.</span><span
class="n">parent</span> <span class="o">=</span> <span class="n">parent</span>
+
+ <span class="k">def</span> <span class="nf">__repr__</span><span
class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">return</span> <span
class="s">"TreeNode(name=</span><span class="si">%r</span><span
class="s">, id=</span><span class="si">%r</span><span class="s">,
parent_id=</span><span class="si">%r</span><span class="s">)"</span> <span
class="o">%</span> <span class="p">(</span>
+ <span class="bp">self</span><span class="o">.</span><span
class="n">name</span><span class="p">,</span>
+ <span class="bp">self</span><span class="o">.</span><span
class="n">id</span><span class="p">,</span>
+ <span class="bp">self</span><span class="o">.</span><span
class="n">parent_id</span>
+ <span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">dump</span><span
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span
class="n">_indent</span><span class="o">=</span><span class="mi">0</span><span
class="p">):</span>
+ <span class="k">return</span> <span class="s">" "</span>
<span class="o">*</span> <span class="n">_indent</span> <span
class="o">+</span> <span class="nb">repr</span><span class="p">(</span><span
class="bp">self</span><span class="p">)</span> <span class="o">+</span> \
+ <span class="s">"</span><span
class="se">\n</span><span class="s">"</span> <span class="o">+</span> \
+ <span class="s">""</span><span
class="o">.</span><span class="n">join</span><span class="p">([</span>
+ <span class="n">c</span><span class="o">.</span><span
class="n">dump</span><span class="p">(</span><span class="n">_indent</span>
<span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
+ <span class="k">for</span> <span class="n">c</span>
<span class="ow">in</span> <span class="bp">self</span><span
class="o">.</span><span class="n">children</span><span class="o">.</span><span
class="n">values</span><span class="p">()]</span>
+ <span class="p">)</span>
+
+<span class="k">if</span> <span class="n">__name__</span> <span
class="o">==</span> <span class="s">'__main__'</span><span
class="p">:</span>
+ <span class="n">engine</span> <span class="o">=</span> <span
class="n">create_engine</span><span class="p">(</span><span
class="s">'sqlite://'</span><span class="p">,</span> <span
class="n">echo</span><span class="o">=</span><span class="bp">True</span><span
class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">msg</span><span
class="p">(</span><span class="n">msg</span><span class="p">,</span> <span
class="o">*</span><span class="n">args</span><span class="p">):</span>
+ <span class="n">msg</span> <span class="o">=</span> <span
class="n">msg</span> <span class="o">%</span> <span class="n">args</span>
+ <span class="k">print</span><span class="p">(</span><span
class="s">"</span><span class="se">\n\n\n</span><span
class="s">"</span> <span class="o">+</span> <span
class="s">"-"</span> <span class="o">*</span> <span
class="nb">len</span><span class="p">(</span><span class="n">msg</span><span
class="o">.</span><span class="n">split</span><span class="p">(</span><span
class="s">"</span><span class="se">\n</span><span
class="s">"</span><span class="p">)[</span><span class="mi">0</span><span
class="p">]))</span>
+ <span class="k">print</span><span class="p">(</span><span
class="n">msg</span><span class="p">)</span>
+ <span class="k">print</span><span class="p">(</span><span
class="s">"-"</span> <span class="o">*</span> <span
class="nb">len</span><span class="p">(</span><span class="n">msg</span><span
class="o">.</span><span class="n">split</span><span class="p">(</span><span
class="s">"</span><span class="se">\n</span><span
class="s">"</span><span class="p">)[</span><span class="mi">0</span><span
class="p">]))</span>
+
+ <span class="n">msg</span><span class="p">(</span><span
class="s">"Creating Tree Table:"</span><span class="p">)</span>
+
+ <span class="n">Base</span><span class="o">.</span><span
class="n">metadata</span><span class="o">.</span><span
class="n">create_all</span><span class="p">(</span><span
class="n">engine</span><span class="p">)</span>
+
+ <span class="n">session</span> <span class="o">=</span> <span
class="n">Session</span><span class="p">(</span><span
class="n">engine</span><span class="p">)</span>
+
+ <span class="n">node</span> <span class="o">=</span> <span
class="n">TreeNode</span><span class="p">(</span><span
class="s">'rootnode'</span><span class="p">)</span>
+ <span class="n">TreeNode</span><span class="p">(</span><span
class="s">'node1'</span><span class="p">,</span> <span
class="n">parent</span><span class="o">=</span><span class="n">node</span><span
class="p">)</span>
+ <span class="n">TreeNode</span><span class="p">(</span><span
class="s">'node3'</span><span class="p">,</span> <span
class="n">parent</span><span class="o">=</span><span class="n">node</span><span
class="p">)</span>
+
+ <span class="n">node2</span> <span class="o">=</span> <span
class="n">TreeNode</span><span class="p">(</span><span
class="s">'node2'</span><span class="p">)</span>
+ <span class="n">TreeNode</span><span class="p">(</span><span
class="s">'subnode1'</span><span class="p">,</span> <span
class="n">parent</span><span class="o">=</span><span
class="n">node2</span><span class="p">)</span>
+ <span class="n">node</span><span class="o">.</span><span
class="n">children</span><span class="p">[</span><span
class="s">'node2'</span><span class="p">]</span> <span
class="o">=</span> <span class="n">node2</span>
+ <span class="n">TreeNode</span><span class="p">(</span><span
class="s">'subnode2'</span><span class="p">,</span> <span
class="n">parent</span><span class="o">=</span><span class="n">node</span><span
class="o">.</span><span class="n">children</span><span class="p">[</span><span
class="s">'node2'</span><span class="p">])</span>
+
+ <span class="n">msg</span><span class="p">(</span><span
class="s">"Created new tree structure:</span><span
class="se">\n</span><span class="si">%s</span><span
class="s">"</span><span class="p">,</span> <span
class="n">node</span><span class="o">.</span><span class="n">dump</span><span
class="p">())</span>
+
+ <span class="n">msg</span><span class="p">(</span><span
class="s">"flush + commit:"</span><span class="p">)</span>
+
+ <span class="n">session</span><span class="o">.</span><span
class="n">add</span><span class="p">(</span><span class="n">node</span><span
class="p">)</span>
+ <span class="n">session</span><span class="o">.</span><span
class="n">commit</span><span class="p">()</span>
+
+ <span class="n">msg</span><span class="p">(</span><span
class="s">"Tree After Save:</span><span class="se">\n</span><span
class="s"> </span><span class="si">%s</span><span class="s">"</span><span
class="p">,</span> <span class="n">node</span><span class="o">.</span><span
class="n">dump</span><span class="p">())</span>
+
+ <span class="n">TreeNode</span><span class="p">(</span><span
class="s">'node4'</span><span class="p">,</span> <span
class="n">parent</span><span class="o">=</span><span class="n">node</span><span
class="p">)</span>
+ <span class="n">TreeNode</span><span class="p">(</span><span
class="s">'subnode3'</span><span class="p">,</span> <span
class="n">parent</span><span class="o">=</span><span class="n">node</span><span
class="o">.</span><span class="n">children</span><span class="p">[</span><span
class="s">'node4'</span><span class="p">])</span>
+ <span class="n">TreeNode</span><span class="p">(</span><span
class="s">'subnode4'</span><span class="p">,</span> <span
class="n">parent</span><span class="o">=</span><span class="n">node</span><span
class="o">.</span><span class="n">children</span><span class="p">[</span><span
class="s">'node4'</span><span class="p">])</span>
+ <span class="n">TreeNode</span><span class="p">(</span><span
class="s">'subsubnode1'</span><span class="p">,</span> <span
class="n">parent</span><span class="o">=</span><span class="n">node</span><span
class="o">.</span><span class="n">children</span><span class="p">[</span><span
class="s">'node4'</span><span class="p">]</span><span
class="o">.</span><span class="n">children</span><span class="p">[</span><span
class="s">'subnode3'</span><span class="p">])</span>
+
+ <span class="c"># remove node1 from the parent, which will trigger a
delete</span>
+ <span class="c"># via the delete-orphan cascade.</span>
+ <span class="k">del</span> <span class="n">node</span><span
class="o">.</span><span class="n">children</span><span class="p">[</span><span
class="s">'node1'</span><span class="p">]</span>
+
+ <span class="n">msg</span><span class="p">(</span><span
class="s">"Removed node1. flush + commit:"</span><span
class="p">)</span>
+ <span class="n">session</span><span class="o">.</span><span
class="n">commit</span><span class="p">()</span>
+
+ <span class="n">msg</span><span class="p">(</span><span
class="s">"Tree after save:</span><span class="se">\n</span><span
class="s"> </span><span class="si">%s</span><span class="s">"</span><span
class="p">,</span> <span class="n">node</span><span class="o">.</span><span
class="n">dump</span><span class="p">())</span>
+
+ <span class="n">msg</span><span class="p">(</span><span
class="s">"Emptying out the session entirely, "</span>
+ <span class="s">"selecting tree on root, using eager loading to
join four levels deep."</span><span class="p">)</span>
+ <span class="n">session</span><span class="o">.</span><span
class="n">expunge_all</span><span class="p">()</span>
+ <span class="n">node</span> <span class="o">=</span> <span
class="n">session</span><span class="o">.</span><span
class="n">query</span><span class="p">(</span><span
class="n">TreeNode</span><span class="p">)</span><span class="o">.</span>\
+ <span class="n">options</span><span
class="p">(</span><span class="n">joinedload_all</span><span
class="p">(</span><span class="s">"children"</span><span
class="p">,</span> <span class="s">"children"</span><span
class="p">,</span>
+ <span
class="s">"children"</span><span class="p">,</span> <span
class="s">"children"</span><span class="p">))</span><span
class="o">.</span>\
+ <span class="nb">filter</span><span
class="p">(</span><span class="n">TreeNode</span><span class="o">.</span><span
class="n">name</span> <span class="o">==</span> <span
class="s">"rootnode"</span><span class="p">)</span><span
class="o">.</span>\
+ <span class="n">first</span><span class="p">()</span>
+
+ <span class="n">msg</span><span class="p">(</span><span
class="s">"Full Tree:</span><span class="se">\n</span><span
class="si">%s</span><span class="s">"</span><span class="p">,</span> <span
class="n">node</span><span class="o">.</span><span class="n">dump</span><span
class="p">())</span>
+
+ <span class="n">msg</span><span class="p">(</span><span
class="s">"Marking root node as deleted, flush + commit:"</span><span
class="p">)</span>
+
+ <span class="n">session</span><span class="o">.</span><span
class="n">delete</span><span class="p">(</span><span class="n">node</span><span
class="p">)</span>
+ <span class="n">session</span><span class="o">.</span><span
class="n">commit</span><span class="p">()</span></pre></div>
+ </div>
+
+</div>
+
+<div id="docs-bottom-navigation" class="docs-navigation-links">
+
+ <div id="docs-copyright">
+ © <a href="../../../copyright.html">Copyright</a> 2007-2015, the
SQLAlchemy authors and contributors.
+ Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.3.1.
+ </div>
+</div>
+
+</div>
+
+
+
+
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '../../../',
+ VERSION: '1.0.11',
+ COLLAPSE_MODINDEX: false,
+ FILE_SUFFIX: '.html'
+ };
+ </script>
+
+ <!-- begin iterate through sphinx environment script_files -->
+ <script type="text/javascript"
src="../../../_static/jquery.js"></script>
+ <script type="text/javascript"
src="../../../_static/underscore.js"></script>
+ <script type="text/javascript"
src="../../../_static/doctools.js"></script>
+ <!-- end iterate through sphinx environment script_files -->
+
+ <script type="text/javascript"
src="../../../_static/detectmobile.js"></script>
+ <script type="text/javascript" src="../../../_static/init.js"></script>
+
+
+ </body>
+</html>
+
+
diff --git
a/lib/sqlalchemy/doc/_modules/examples/association/basic_association.html
b/lib/sqlalchemy/doc/_modules/examples/association/basic_association.html
new file mode 100644
--- /dev/null
+++ b/lib/sqlalchemy/doc/_modules/examples/association/basic_association.html
@@ -0,0 +1,240 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>
+
+
+ examples.association.basic_association
+ —
+ SQLAlchemy 1.0 Documentation
+
+ </title>
+
+
+ <!-- begin iterate through SQLA + sphinx environment css_files -->
+ <link rel="stylesheet" href="../../../_static/pygments.css"
type="text/css" />
+ <link rel="stylesheet" href="../../../_static/changelog.css"
type="text/css" />
+ <link rel="stylesheet"
href="../../../_static/sphinx_paramlinks.css" type="text/css" />
+ <link rel="stylesheet" href="../../../_static/docs.css"
type="text/css" />
+ <!-- end iterate through SQLA + sphinx environment css_files -->
+
+
+
+
+
+
+ <!-- begin layout.mako headers -->
+
+ <link rel="index" title="Index" href="../../../genindex.html" />
+ <link rel="search" title="Search" href="../../../search.html" />
+ <link rel="copyright" title="Copyright" href="../../../copyright.html"
/>
+ <link rel="top" title="SQLAlchemy 1.0 Documentation"
href="../../../index.html" />
+ <link rel="up" title="Module code" href="../../index.html" />
+ <!-- end layout.mako headers -->
+
+
+ </head>
+ <body>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<div id="docs-container">
+
+
+
+
+
+<div id="docs-top-navigation-container" class="body-background">
+<div id="docs-header">
+ <div id="docs-version-header">
+ Release: <span class="version-num">1.0.11</span> | Release Date:
December 12, 2015
+ </div>
+
+ <h1>SQLAlchemy 1.0 Documentation</h1>
+
+</div>
+</div>
+
+<div id="docs-body-container">
+
+ <div id="fixed-sidebar" class="">
+
+ <div id="index-nav">
+ <form class="search" action="../../../search.html" method="get">
+ <input type="text" name="q" size="12" /> <input type="submit"
value="Search" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+
+ <p>
+ <a href="../../../contents.html">Contents</a> |
+ <a href="../../../genindex.html">Index</a>
+ </p>
+
+ </div>
+
+
+ </div>
+
+
+
+ <div id="docs-body" class="" >
+
+<h1>Source code for examples.association.basic_association</h1><div
class="highlight"><pre>
+<span class="sd">"""basic_association.py</span>
+
+<span class="sd">illustrate a many-to-many relationship between an</span>
+<span class="sd">"Order" and a collection of "Item"
objects, associating a purchase price</span>
+<span class="sd">with each via an association object called
"OrderItem"</span>
+
+<span class="sd">The association object pattern is a form of many-to-many
which</span>
+<span class="sd">associates additional data with each association between
parent/child.</span>
+
+<span class="sd">The example illustrates an "order", referencing a
collection</span>
+<span class="sd">of "items", with a particular price paid associated
with each "item".</span>
+
+<span class="sd">"""</span>
+
+<span class="kn">from</span> <span class="nn">datetime</span> <span
class="kn">import</span> <span class="n">datetime</span>
+
+<span class="kn">from</span> <span class="nn">sqlalchemy</span> <span
class="kn">import</span> <span class="p">(</span><span
class="n">create_engine</span><span class="p">,</span> <span
class="n">MetaData</span><span class="p">,</span> <span
class="n">Table</span><span class="p">,</span> <span
class="n">Column</span><span class="p">,</span> <span
class="n">Integer</span><span class="p">,</span>
+ <span class="n">String</span><span class="p">,</span> <span
class="n">DateTime</span><span class="p">,</span> <span
class="n">Float</span><span class="p">,</span> <span
class="n">ForeignKey</span><span class="p">,</span> <span
class="n">and_</span><span class="p">)</span>
+<span class="kn">from</span> <span class="nn">sqlalchemy.orm</span> <span
class="kn">import</span> <span class="n">mapper</span><span class="p">,</span>
<span class="n">relationship</span><span class="p">,</span> <span
class="n">Session</span>
+<span class="kn">from</span> <span
class="nn">sqlalchemy.ext.declarative</span> <span class="kn">import</span>
<span class="n">declarative_base</span>
+
+<span class="n">Base</span> <span class="o">=</span> <span
class="n">declarative_base</span><span class="p">()</span>
+
+<span class="k">class</span> <span class="nc">Order</span><span
class="p">(</span><span class="n">Base</span><span class="p">):</span>
+ <span class="n">__tablename__</span> <span class="o">=</span> <span
class="s">'order'</span>
+
+ <span class="n">order_id</span> <span class="o">=</span> <span
class="n">Column</span><span class="p">(</span><span
class="n">Integer</span><span class="p">,</span> <span
class="n">primary_key</span><span class="o">=</span><span
class="bp">True</span><span class="p">)</span>
+ <span class="n">customer_name</span> <span class="o">=</span> <span
class="n">Column</span><span class="p">(</span><span
class="n">String</span><span class="p">(</span><span class="mi">30</span><span
class="p">),</span> <span class="n">nullable</span><span
class="o">=</span><span class="bp">False</span><span class="p">)</span>
+ <span class="n">order_date</span> <span class="o">=</span> <span
class="n">Column</span><span class="p">(</span><span
class="n">DateTime</span><span class="p">,</span> <span
class="n">nullable</span><span class="o">=</span><span
class="bp">False</span><span class="p">,</span> <span
class="n">default</span><span class="o">=</span><span
class="n">datetime</span><span class="o">.</span><span
class="n">now</span><span class="p">())</span>
+ <span class="n">order_items</span> <span class="o">=</span> <span
class="n">relationship</span><span class="p">(</span><span
class="s">"OrderItem"</span><span class="p">,</span> <span
class="n">cascade</span><span class="o">=</span><span class="s">"all,
delete-orphan"</span><span class="p">,</span>
+ <span class="n">backref</span><span
class="o">=</span><span class="s">'order'</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span
class="n">customer_name</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span
class="n">customer_name</span> <span class="o">=</span> <span
class="n">customer_name</span>
+
+<span class="k">class</span> <span class="nc">Item</span><span
class="p">(</span><span class="n">Base</span><span class="p">):</span>
+ <span class="n">__tablename__</span> <span class="o">=</span> <span
class="s">'item'</span>
+ <span class="n">item_id</span> <span class="o">=</span> <span
class="n">Column</span><span class="p">(</span><span
class="n">Integer</span><span class="p">,</span> <span
class="n">primary_key</span><span class="o">=</span><span
class="bp">True</span><span class="p">)</span>
+ <span class="n">description</span> <span class="o">=</span> <span
class="n">Column</span><span class="p">(</span><span
class="n">String</span><span class="p">(</span><span class="mi">30</span><span
class="p">),</span> <span class="n">nullable</span><span
class="o">=</span><span class="bp">False</span><span class="p">)</span>
+ <span class="n">price</span> <span class="o">=</span> <span
class="n">Column</span><span class="p">(</span><span
class="n">Float</span><span class="p">,</span> <span
class="n">nullable</span><span class="o">=</span><span
class="bp">False</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span
class="n">description</span><span class="p">,</span> <span
class="n">price</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span
class="n">description</span> <span class="o">=</span> <span
class="n">description</span>
+ <span class="bp">self</span><span class="o">.</span><span
class="n">price</span> <span class="o">=</span> <span class="n">price</span>
+
+ <span class="k">def</span> <span class="nf">__repr__</span><span
class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">return</span> <span class="s">'Item(</span><span
class="si">%r</span><span class="s">, </span><span class="si">%r</span><span
class="s">)'</span> <span class="o">%</span> <span class="p">(</span>
+ <span class="bp">self</span><span class="o">.</span><span
class="n">description</span><span class="p">,</span> <span
class="bp">self</span><span class="o">.</span><span class="n">price</span>
+ <span class="p">)</span>
+
+<span class="k">class</span> <span class="nc">OrderItem</span><span
class="p">(</span><span class="n">Base</span><span class="p">):</span>
+ <span class="n">__tablename__</span> <span class="o">=</span> <span
class="s">'orderitem'</span>
+ <span class="n">order_id</span> <span class="o">=</span> <span
class="n">Column</span><span class="p">(</span><span
class="n">Integer</span><span class="p">,</span> <span
class="n">ForeignKey</span><span class="p">(</span><span
class="s">'order.order_id'</span><span class="p">),</span> <span
class="n">primary_key</span><span class="o">=</span><span
class="bp">True</span><span class="p">)</span>
+ <span class="n">item_id</span> <span class="o">=</span> <span
class="n">Column</span><span class="p">(</span><span
class="n">Integer</span><span class="p">,</span> <span
class="n">ForeignKey</span><span class="p">(</span><span
class="s">'item.item_id'</span><span class="p">),</span> <span
class="n">primary_key</span><span class="o">=</span><span
class="bp">True</span><span class="p">)</span>
+ <span class="n">price</span> <span class="o">=</span> <span
class="n">Column</span><span class="p">(</span><span
class="n">Float</span><span class="p">,</span> <span
class="n">nullable</span><span class="o">=</span><span
class="bp">False</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span
class="n">item</span><span class="p">,</span> <span class="n">price</span><span
class="o">=</span><span class="bp">None</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span
class="n">item</span> <span class="o">=</span> <span class="n">item</span>
+ <span class="bp">self</span><span class="o">.</span><span
class="n">price</span> <span class="o">=</span> <span class="n">price</span>
<span class="ow">or</span> <span class="n">item</span><span
class="o">.</span><span class="n">price</span>
+ <span class="n">item</span> <span class="o">=</span> <span
class="n">relationship</span><span class="p">(</span><span
class="n">Item</span><span class="p">,</span> <span class="n">lazy</span><span
class="o">=</span><span class="s">'joined'</span><span
class="p">)</span>
+
+<span class="k">if</span> <span class="n">__name__</span> <span
class="o">==</span> <span class="s">'__main__'</span><span
class="p">:</span>
+ <span class="n">engine</span> <span class="o">=</span> <span
class="n">create_engine</span><span class="p">(</span><span
class="s">'sqlite://'</span><span class="p">)</span>
+ <span class="n">Base</span><span class="o">.</span><span
class="n">metadata</span><span class="o">.</span><span
class="n">create_all</span><span class="p">(</span><span
class="n">engine</span><span class="p">)</span>
+
+ <span class="n">session</span> <span class="o">=</span> <span
class="n">Session</span><span class="p">(</span><span
class="n">engine</span><span class="p">)</span>
+
+ <span class="c"># create catalog</span>
+ <span class="n">tshirt</span><span class="p">,</span> <span
class="n">mug</span><span class="p">,</span> <span class="n">hat</span><span
class="p">,</span> <span class="n">crowbar</span> <span class="o">=</span>
<span class="p">(</span>
+ <span class="n">Item</span><span class="p">(</span><span
class="s">'SA T-Shirt'</span><span class="p">,</span> <span
class="mf">10.99</span><span class="p">),</span>
+ <span class="n">Item</span><span class="p">(</span><span
class="s">'SA Mug'</span><span class="p">,</span> <span
class="mf">6.50</span><span class="p">),</span>
+ <span class="n">Item</span><span class="p">(</span><span
class="s">'SA Hat'</span><span class="p">,</span> <span
class="mf">8.99</span><span class="p">),</span>
+ <span class="n">Item</span><span class="p">(</span><span
class="s">'MySQL Crowbar'</span><span class="p">,</span> <span
class="mf">16.99</span><span class="p">)</span>
+ <span class="p">)</span>
+ <span class="n">session</span><span class="o">.</span><span
class="n">add_all</span><span class="p">([</span><span
class="n">tshirt</span><span class="p">,</span> <span class="n">mug</span><span
class="p">,</span> <span class="n">hat</span><span class="p">,</span> <span
class="n">crowbar</span><span class="p">])</span>
+ <span class="n">session</span><span class="o">.</span><span
class="n">commit</span><span class="p">()</span>
+
+ <span class="c"># create an order</span>
+ <span class="n">order</span> <span class="o">=</span> <span
class="n">Order</span><span class="p">(</span><span class="s">'john
smith'</span><span class="p">)</span>
+
+ <span class="c"># add three OrderItem associations to the Order and
save</span>
+ <span class="n">order</span><span class="o">.</span><span
class="n">order_items</span><span class="o">.</span><span
class="n">append</span><span class="p">(</span><span
class="n">OrderItem</span><span class="p">(</span><span
class="n">mug</span><span class="p">))</span>
+ <span class="n">order</span><span class="o">.</span><span
class="n">order_items</span><span class="o">.</span><span
class="n">append</span><span class="p">(</span><span
class="n">OrderItem</span><span class="p">(</span><span
class="n">crowbar</span><span class="p">,</span> <span
class="mf">10.99</span><span class="p">))</span>
+ <span class="n">order</span><span class="o">.</span><span
class="n">order_items</span><span class="o">.</span><span
class="n">append</span><span class="p">(</span><span
class="n">OrderItem</span><span class="p">(</span><span
class="n">hat</span><span class="p">))</span>
+ <span class="n">session</span><span class="o">.</span><span
class="n">add</span><span class="p">(</span><span class="n">order</span><span
class="p">)</span>
+ <span class="n">session</span><span class="o">.</span><span
class="n">commit</span><span class="p">()</span>
+
+ <span class="c"># query the order, print items</span>
+ <span class="n">order</span> <span class="o">=</span> <span
class="n">session</span><span class="o">.</span><span
class="n">query</span><span class="p">(</span><span class="n">Order</span><span
class="p">)</span><span class="o">.</span><span class="n">filter_by</span><span
class="p">(</span><span class="n">customer_name</span><span
class="o">=</span><span class="s">'john smith'</span><span
class="p">)</span><span class="o">.</span><span class="n">one</span><span
class="p">()</span>
+ <span class="k">print</span><span class="p">([(</span><span
class="n">order_item</span><span class="o">.</span><span
class="n">item</span><span class="o">.</span><span
class="n">description</span><span class="p">,</span> <span
class="n">order_item</span><span class="o">.</span><span
class="n">price</span><span class="p">)</span>
+ <span class="k">for</span> <span class="n">order_item</span> <span
class="ow">in</span> <span class="n">order</span><span class="o">.</span><span
class="n">order_items</span><span class="p">])</span>
+
+ <span class="c"># print customers who bought 'MySQL Crowbar' on
sale</span>
+ <span class="n">q</span> <span class="o">=</span> <span
class="n">session</span><span class="o">.</span><span
class="n">query</span><span class="p">(</span><span class="n">Order</span><span
class="p">)</span><span class="o">.</span><span class="n">join</span><span
class="p">(</span><span class="s">'order_items'</span><span
class="p">,</span> <span class="s">'item'</span><span class="p">)</span>
+ <span class="n">q</span> <span class="o">=</span> <span
class="n">q</span><span class="o">.</span><span class="n">filter</span><span
class="p">(</span><span class="n">and_</span><span class="p">(</span><span
class="n">Item</span><span class="o">.</span><span class="n">description</span>
<span class="o">==</span> <span class="s">'MySQL Crowbar'</span><span
class="p">,</span>
+ <span class="n">Item</span><span class="o">.</span><span
class="n">price</span> <span class="o">></span> <span
class="n">OrderItem</span><span class="o">.</span><span
class="n">price</span><span class="p">))</span>
+
+ <span class="k">print</span><span class="p">([</span><span
class="n">order</span><span class="o">.</span><span
class="n">customer_name</span> <span class="k">for</span> <span
class="n">order</span> <span class="ow">in</span> <span class="n">q</span><span
class="p">])</span></pre></div>
+ </div>
+
+</div>
+
+<div id="docs-bottom-navigation" class="docs-navigation-links">
+
+ <div id="docs-copyright">
+ © <a href="../../../copyright.html">Copyright</a> 2007-2015, the
SQLAlchemy authors and contributors.
+ Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.3.1.
+ </div>
+</div>
+
+</div>
+
+
+
+
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '../../../',
+ VERSION: '1.0.11',
+ COLLAPSE_MODINDEX: false,
+ FILE_SUFFIX: '.html'
+ };
+ </script>
+
+ <!-- begin iterate through sphinx environment script_files -->
+ <script type="text/javascript"
src="../../../_static/jquery.js"></script>
+ <script type="text/javascript"
src="../../../_static/underscore.js"></script>
+ <script type="text/javascript"
src="../../../_static/doctools.js"></script>
+ <!-- end iterate through sphinx environment script_files -->
+
+ <script type="text/javascript"
src="../../../_static/detectmobile.js"></script>
+ <script type="text/javascript" src="../../../_static/init.js"></script>
+
+
+ </body>
+</html>
+
+
diff --git
a/lib/sqlalchemy/doc/_modules/examples/association/dict_of_sets_with_default.html
b/lib/sqlalchemy/doc/_modules/examples/association/dict_of_sets_with_default.html
new file mode 100644
--- /dev/null
+++
b/lib/sqlalchemy/doc/_modules/examples/association/dict_of_sets_with_default.html
@@ -0,0 +1,232 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>
+
+
+ examples.association.dict_of_sets_with_default
+ —
+ SQLAlchemy 1.0 Documentation
+
+ </title>
+
+
+ <!-- begin iterate through SQLA + sphinx environment css_files -->
+ <link rel="stylesheet" href="../../../_static/pygments.css"
type="text/css" />
+ <link rel="stylesheet" href="../../../_static/changelog.css"
type="text/css" />
+ <link rel="stylesheet"
href="../../../_static/sphinx_paramlinks.css" type="text/css" />
+ <link rel="stylesheet" href="../../../_static/docs.css"
type="text/css" />
+ <!-- end iterate through SQLA + sphinx environment css_files -->
+
+
+
+
+
+
+ <!-- begin layout.mako headers -->
+
+ <link rel="index" title="Index" href="../../../genindex.html" />
+ <link rel="search" title="Search" href="../../../search.html" />
+ <link rel="copyright" title="Copyright" href="../../../copyright.html"
/>
+ <link rel="top" title="SQLAlchemy 1.0 Documentation"
href="../../../index.html" />
+ <link rel="up" title="Module code" href="../../index.html" />
+ <!-- end layout.mako headers -->
+
+
+ </head>
+ <body>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<div id="docs-container">
+
+
+
+
+
+<div id="docs-top-navigation-container" class="body-background">
+<div id="docs-header">
+ <div id="docs-version-header">
+ Release: <span class="version-num">1.0.11</span> | Release Date:
December 12, 2015
+ </div>
+
+ <h1>SQLAlchemy 1.0 Documentation</h1>
+
+</div>
+</div>
+
+<div id="docs-body-container">
+
+ <div id="fixed-sidebar" class="">
+
+ <div id="index-nav">
+ <form class="search" action="../../../search.html" method="get">
+ <input type="text" name="q" size="12" /> <input type="submit"
value="Search" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+
+ <p>
+ <a href="../../../contents.html">Contents</a> |
+ <a href="../../../genindex.html">Index</a>
+ </p>
+
+ </div>
+
+
+ </div>
+
+
+
+ <div id="docs-body" class="" >
+
+<h1>Source code for examples.association.dict_of_sets_with_default</h1><div
class="highlight"><pre>
+<span class="sd">"""dict_of_sets_with_default.py</span>
+
+<span class="sd">an advanced association proxy example which</span>
+<span class="sd">illustrates nesting of association proxies to produce
multi-level Python</span>
+<span class="sd">collections, in this case a dictionary with string keys and
sets of integers</span>
+<span class="sd">as values, which conceal the underlying mapped classes.</span>
+
+<span class="sd">This is a three table model which represents a parent table
referencing a</span>
+<span class="sd">dictionary of string keys and sets as values, where each set
stores a</span>
+<span class="sd">collection of integers. The association proxy extension is
used to hide the</span>
+<span class="sd">details of this persistence. The dictionary also generates
new collections</span>
+<span class="sd">upon access of a non-existent key, in the same manner as
Python's</span>
+<span class="sd">"collections.defaultdict" object.</span>
+
+<span class="sd">"""</span>
+
+<span class="kn">from</span> <span class="nn">sqlalchemy</span> <span
class="kn">import</span> <span class="n">String</span><span class="p">,</span>
<span class="n">Integer</span><span class="p">,</span> <span
class="n">Column</span><span class="p">,</span> <span
class="n">create_engine</span><span class="p">,</span> <span
class="n">ForeignKey</span>
+<span class="kn">from</span> <span class="nn">sqlalchemy.orm</span> <span
class="kn">import</span> <span class="n">relationship</span><span
class="p">,</span> <span class="n">Session</span>
+<span class="kn">from</span> <span
class="nn">sqlalchemy.orm.collections</span> <span class="kn">import</span>
<span class="n">MappedCollection</span>
+<span class="kn">from</span> <span
class="nn">sqlalchemy.ext.declarative</span> <span class="kn">import</span>
<span class="n">declarative_base</span>
+<span class="kn">from</span> <span
class="nn">sqlalchemy.ext.associationproxy</span> <span
class="kn">import</span> <span class="n">association_proxy</span>
+<span class="kn">import</span> <span class="nn">operator</span>
+
+<span class="k">class</span> <span class="nc">Base</span><span
class="p">(</span><span class="nb">object</span><span class="p">):</span>
+ <span class="nb">id</span> <span class="o">=</span> <span
class="n">Column</span><span class="p">(</span><span
class="n">Integer</span><span class="p">,</span> <span
class="n">primary_key</span><span class="o">=</span><span
class="bp">True</span><span class="p">)</span>
+
+<span class="n">Base</span> <span class="o">=</span> <span
class="n">declarative_base</span><span class="p">(</span><span
class="n">cls</span><span class="o">=</span><span class="n">Base</span><span
class="p">)</span>
+
+<span class="k">class</span> <span class="nc">GenDefaultCollection</span><span
class="p">(</span><span class="n">MappedCollection</span><span
class="p">):</span>
+ <span class="k">def</span> <span class="nf">__missing__</span><span
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span
class="n">key</span><span class="p">):</span>
+ <span class="bp">self</span><span class="p">[</span><span
class="n">key</span><span class="p">]</span> <span class="o">=</span> <span
class="n">b</span> <span class="o">=</span> <span class="n">B</span><span
class="p">(</span><span class="n">key</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">b</span>
+
+<span class="k">class</span> <span class="nc">A</span><span
class="p">(</span><span class="n">Base</span><span class="p">):</span>
+ <span class="n">__tablename__</span> <span class="o">=</span> <span
class="s">"a"</span>
+ <span class="n">associations</span> <span class="o">=</span> <span
class="n">relationship</span><span class="p">(</span><span
class="s">"B"</span><span class="p">,</span>
+ <span class="n">collection_class</span><span class="o">=</span><span
class="k">lambda</span><span class="p">:</span> <span
class="n">GenDefaultCollection</span><span class="p">(</span><span
class="n">operator</span><span class="o">.</span><span
class="n">attrgetter</span><span class="p">(</span><span
class="s">"key"</span><span class="p">))</span>
+ <span class="p">)</span>
+
+ <span class="n">collections</span> <span class="o">=</span> <span
class="n">association_proxy</span><span class="p">(</span><span
class="s">"associations"</span><span class="p">,</span> <span
class="s">"values"</span><span class="p">)</span>
+ <span class="sd">"""Bridge the association from
'associations' over to the 'values'</span>
+<span class="sd"> association proxy of B.</span>
+<span class="sd"> """</span>
+
+<span class="k">class</span> <span class="nc">B</span><span
class="p">(</span><span class="n">Base</span><span class="p">):</span>
+ <span class="n">__tablename__</span> <span class="o">=</span> <span
class="s">"b"</span>
+ <span class="n">a_id</span> <span class="o">=</span> <span
class="n">Column</span><span class="p">(</span><span
class="n">Integer</span><span class="p">,</span> <span
class="n">ForeignKey</span><span class="p">(</span><span
class="s">"a.id"</span><span class="p">),</span> <span
class="n">nullable</span><span class="o">=</span><span
class="bp">False</span><span class="p">)</span>
+ <span class="n">elements</span> <span class="o">=</span> <span
class="n">relationship</span><span class="p">(</span><span
class="s">"C"</span><span class="p">,</span> <span
class="n">collection_class</span><span class="o">=</span><span
class="nb">set</span><span class="p">)</span>
+ <span class="n">key</span> <span class="o">=</span> <span
class="n">Column</span><span class="p">(</span><span
class="n">String</span><span class="p">)</span>
+
+ <span class="n">values</span> <span class="o">=</span> <span
class="n">association_proxy</span><span class="p">(</span><span
class="s">"elements"</span><span class="p">,</span> <span
class="s">"value"</span><span class="p">)</span>
+ <span class="sd">"""Bridge the association from
'elements' over to the</span>
+<span class="sd"> 'value' element of C."""</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span
class="n">key</span><span class="p">,</span> <span class="n">values</span><span
class="o">=</span><span class="bp">None</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span
class="n">key</span> <span class="o">=</span> <span class="n">key</span>
+ <span class="k">if</span> <span class="n">values</span><span
class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span
class="n">values</span> <span class="o">=</span> <span class="n">values</span>
+
+<span class="k">class</span> <span class="nc">C</span><span
class="p">(</span><span class="n">Base</span><span class="p">):</span>
+ <span class="n">__tablename__</span> <span class="o">=</span> <span
class="s">"c"</span>
+ <span class="n">b_id</span> <span class="o">=</span> <span
class="n">Column</span><span class="p">(</span><span
class="n">Integer</span><span class="p">,</span> <span
class="n">ForeignKey</span><span class="p">(</span><span
class="s">"b.id"</span><span class="p">),</span> <span
class="n">nullable</span><span class="o">=</span><span
class="bp">False</span><span class="p">)</span>
+ <span class="n">value</span> <span class="o">=</span> <span
class="n">Column</span><span class="p">(</span><span
class="n">Integer</span><span class="p">)</span>
+ <span class="k">def</span> <span class="nf">__init__</span><span
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span
class="n">value</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span
class="n">value</span> <span class="o">=</span> <span class="n">value</span>
+
+<span class="k">if</span> <span class="n">__name__</span> <span
class="o">==</span> <span class="s">'__main__'</span><span
class="p">:</span>
+ <span class="n">engine</span> <span class="o">=</span> <span
class="n">create_engine</span><span class="p">(</span><span
class="s">'sqlite://'</span><span class="p">,</span> <span
class="n">echo</span><span class="o">=</span><span class="bp">True</span><span
class="p">)</span>
+ <span class="n">Base</span><span class="o">.</span><span
class="n">metadata</span><span class="o">.</span><span
class="n">create_all</span><span class="p">(</span><span
class="n">engine</span><span class="p">)</span>
+ <span class="n">session</span> <span class="o">=</span> <span
class="n">Session</span><span class="p">(</span><span
class="n">engine</span><span class="p">)</span>
+
+ <span class="c"># only "A" is referenced explicitly. Using
"collections",</span>
+ <span class="c"># we deal with a dict of key/sets of integers
directly.</span>
+
+ <span class="n">session</span><span class="o">.</span><span
class="n">add_all</span><span class="p">([</span>
+ <span class="n">A</span><span class="p">(</span><span
class="n">collections</span><span class="o">=</span><span class="p">{</span>
+ <span class="s">"1"</span><span class="p">:</span> <span
class="nb">set</span><span class="p">([</span><span class="mi">1</span><span
class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span
class="mi">3</span><span class="p">]),</span>
+ <span class="p">})</span>
+ <span class="p">])</span>
+ <span class="n">session</span><span class="o">.</span><span
class="n">commit</span><span class="p">()</span>
+
+ <span class="n">a1</span> <span class="o">=</span> <span
class="n">session</span><span class="o">.</span><span
class="n">query</span><span class="p">(</span><span class="n">A</span><span
class="p">)</span><span class="o">.</span><span class="n">first</span><span
class="p">()</span>
+ <span class="k">print</span><span class="p">(</span><span
class="n">a1</span><span class="o">.</span><span
class="n">collections</span><span class="p">[</span><span
class="s">"1"</span><span class="p">])</span>
+ <span class="n">a1</span><span class="o">.</span><span
class="n">collections</span><span class="p">[</span><span
class="s">"1"</span><span class="p">]</span><span
class="o">.</span><span class="n">add</span><span class="p">(</span><span
class="mi">4</span><span class="p">)</span>
+ <span class="n">session</span><span class="o">.</span><span
class="n">commit</span><span class="p">()</span>
+
+ <span class="n">a1</span><span class="o">.</span><span
class="n">collections</span><span class="p">[</span><span
class="s">"2"</span><span class="p">]</span><span
class="o">.</span><span class="n">update</span><span class="p">([</span><span
class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span
class="p">,</span> <span class="mi">9</span><span class="p">])</span>
+ <span class="n">session</span><span class="o">.</span><span
class="n">commit</span><span class="p">()</span>
+
+ <span class="k">print</span><span class="p">(</span><span
class="n">a1</span><span class="o">.</span><span
class="n">collections</span><span class="p">[</span><span
class="s">"2"</span><span class="p">])</span></pre></div>
+ </div>
+
+</div>
+
+<div id="docs-bottom-navigation" class="docs-navigation-links">
+
+ <div id="docs-copyright">
+ © <a href="../../../copyright.html">Copyright</a> 2007-2015, the
SQLAlchemy authors and contributors.
+ Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.3.1.
+ </div>
+</div>
+
+</div>
+
+
+
+
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '../../../',
+ VERSION: '1.0.11',
+ COLLAPSE_MODINDEX: false,
+ FILE_SUFFIX: '.html'
+ };
+ </script>
+
+ <!-- begin iterate through sphinx environment script_files -->
+ <script type="text/javascript"
src="../../../_static/jquery.js"></script>
+ <script type="text/javascript"
src="../../../_static/underscore.js"></script>
+ <script type="text/javascript"
src="../../../_static/doctools.js"></script>
+ <!-- end iterate through sphinx environment script_files -->
+
+ <script type="text/javascript"
src="../../../_static/detectmobile.js"></script>
+ <script type="text/javascript" src="../../../_static/init.js"></script>
+
+
+ </body>
+</html>
+
+
diff --git
a/lib/sqlalchemy/doc/_modules/examples/association/proxied_association.html
b/lib/sqlalchemy/doc/_modules/examples/association/proxied_association.html
new file mode 100644
--- /dev/null
+++ b/lib/sqlalchemy/doc/_modules/examples/association/proxied_association.html
@@ -0,0 +1,247 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>
+
+
+ examples.association.proxied_association
+ —
+ SQLAlchemy 1.0 Documentation
+
+ </title>
+
+
+ <!-- begin iterate through SQLA + sphinx environment css_files -->
+ <link rel="stylesheet" href="../../../_static/pygments.css"
type="text/css" />
+ <link rel="stylesheet" href="../../../_static/changelog.css"
type="text/css" />
+ <link rel="stylesheet"
href="../../../_static/sphinx_paramlinks.css" type="text/css" />
+ <link rel="stylesheet" href="../../../_static/docs.css"
type="text/css" />
+ <!-- end iterate through SQLA + sphinx environment css_files -->
+
+
+
+
+
+
+ <!-- begin layout.mako headers -->
+
+ <link rel="index" title="Index" href="../../../genindex.html" />
+ <link rel="search" title="Search" href="../../../search.html" />
+ <link rel="copyright" title="Copyright" href="../../../copyright.html"
/>
+ <link rel="top" title="SQLAlchemy 1.0 Documentation"
href="../../../index.html" />
+ <link rel="up" title="Module code" href="../../index.html" />
+ <!-- end layout.mako headers -->
+
+
+ </head>
+ <body>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<div id="docs-container">
+
+
+
+
+
+<div id="docs-top-navigation-container" class="body-background">
+<div id="docs-header">
+ <div id="docs-version-header">
+ Release: <span class="version-num">1.0.11</span> | Release Date:
December 12, 2015
+ </div>
+
+ <h1>SQLAlchemy 1.0 Documentation</h1>
+
+</div>
+</div>
+
+<div id="docs-body-container">
+
+ <div id="fixed-sidebar" class="">
+
+ <div id="index-nav">
+ <form class="search" action="../../../search.html" method="get">
+ <input type="text" name="q" size="12" /> <input type="submit"
value="Search" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+
+ <p>
+ <a href="../../../contents.html">Contents</a> |
+ <a href="../../../genindex.html">Index</a>
+ </p>
+
+ </div>
+
+
+ </div>
+
+
+
+ <div id="docs-body" class="" >
+
+<h1>Source code for examples.association.proxied_association</h1><div
class="highlight"><pre>
+<span class="sd">"""proxied_association.py</span>
+
+<span class="sd">same example as basic_association, adding in</span>
+<span class="sd">usage of :mod:`sqlalchemy.ext.associationproxy` to make
explicit references</span>
+<span class="sd">to ``OrderItem`` optional.</span>
+
+
+<span class="sd">"""</span>
+
+<span class="kn">from</span> <span class="nn">datetime</span> <span
class="kn">import</span> <span class="n">datetime</span>
+
+<span class="kn">from</span> <span class="nn">sqlalchemy</span> <span
class="kn">import</span> <span class="p">(</span><span
class="n">create_engine</span><span class="p">,</span> <span
class="n">MetaData</span><span class="p">,</span> <span
class="n">Table</span><span class="p">,</span> <span
class="n">Column</span><span class="p">,</span> <span
class="n">Integer</span><span class="p">,</span>
+ <span class="n">String</span><span class="p">,</span> <span
class="n">DateTime</span><span class="p">,</span> <span
class="n">Float</span><span class="p">,</span> <span
class="n">ForeignKey</span><span class="p">,</span> <span
class="n">and_</span><span class="p">)</span>
+<span class="kn">from</span> <span class="nn">sqlalchemy.orm</span> <span
class="kn">import</span> <span class="n">mapper</span><span class="p">,</span>
<span class="n">relationship</span><span class="p">,</span> <span
class="n">Session</span>
+<span class="kn">from</span> <span
class="nn">sqlalchemy.ext.declarative</span> <span class="kn">import</span>
<span class="n">declarative_base</span>
+<span class="kn">from</span> <span
class="nn">sqlalchemy.ext.associationproxy</span> <span
class="kn">import</span> <span class="n">association_proxy</span>
+
+<span class="n">Base</span> <span class="o">=</span> <span
class="n">declarative_base</span><span class="p">()</span>
+
+<span class="k">class</span> <span class="nc">Order</span><span
class="p">(</span><span class="n">Base</span><span class="p">):</span>
+ <span class="n">__tablename__</span> <span class="o">=</span> <span
class="s">'order'</span>
+
+ <span class="n">order_id</span> <span class="o">=</span> <span
class="n">Column</span><span class="p">(</span><span
class="n">Integer</span><span class="p">,</span> <span
class="n">primary_key</span><span class="o">=</span><span
class="bp">True</span><span class="p">)</span>
+ <span class="n">customer_name</span> <span class="o">=</span> <span
class="n">Column</span><span class="p">(</span><span
class="n">String</span><span class="p">(</span><span class="mi">30</span><span
class="p">),</span> <span class="n">nullable</span><span
class="o">=</span><span class="bp">False</span><span class="p">)</span>
+ <span class="n">order_date</span> <span class="o">=</span> <span
class="n">Column</span><span class="p">(</span><span
class="n">DateTime</span><span class="p">,</span> <span
class="n">nullable</span><span class="o">=</span><span
class="bp">False</span><span class="p">,</span> <span
class="n">default</span><span class="o">=</span><span
class="n">datetime</span><span class="o">.</span><span
class="n">now</span><span class="p">())</span>
+ <span class="n">order_items</span> <span class="o">=</span> <span
class="n">relationship</span><span class="p">(</span><span
class="s">"OrderItem"</span><span class="p">,</span> <span
class="n">cascade</span><span class="o">=</span><span class="s">"all,
delete-orphan"</span><span class="p">,</span>
+ <span class="n">backref</span><span
class="o">=</span><span class="s">'order'</span><span class="p">)</span>
+ <span class="n">items</span> <span class="o">=</span> <span
class="n">association_proxy</span><span class="p">(</span><span
class="s">"order_items"</span><span class="p">,</span> <span
class="s">"item"</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span
class="n">customer_name</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span
class="n">customer_name</span> <span class="o">=</span> <span
class="n">customer_name</span>
+
+<span class="k">class</span> <span class="nc">Item</span><span
class="p">(</span><span class="n">Base</span><span class="p">):</span>
+ <span class="n">__tablename__</span> <span class="o">=</span> <span
class="s">'item'</span>
+ <span class="n">item_id</span> <span class="o">=</span> <span
class="n">Column</span><span class="p">(</span><span
class="n">Integer</span><span class="p">,</span> <span
class="n">primary_key</span><span class="o">=</span><span
class="bp">True</span><span class="p">)</span>
+ <span class="n">description</span> <span class="o">=</span> <span
class="n">Column</span><span class="p">(</span><span
class="n">String</span><span class="p">(</span><span class="mi">30</span><span
class="p">),</span> <span class="n">nullable</span><span
class="o">=</span><span class="bp">False</span><span class="p">)</span>
+ <span class="n">price</span> <span class="o">=</span> <span
class="n">Column</span><span class="p">(</span><span
class="n">Float</span><span class="p">,</span> <span
class="n">nullable</span><span class="o">=</span><span
class="bp">False</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span
class="n">description</span><span class="p">,</span> <span
class="n">price</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span
class="n">description</span> <span class="o">=</span> <span
class="n">description</span>
+ <span class="bp">self</span><span class="o">.</span><span
class="n">price</span> <span class="o">=</span> <span class="n">price</span>
+
+ <span class="k">def</span> <span class="nf">__repr__</span><span
class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">return</span> <span class="s">'Item(</span><span
class="si">%r</span><span class="s">, </span><span class="si">%r</span><span
class="s">)'</span> <span class="o">%</span> <span class="p">(</span>
+ <span class="bp">self</span><span class="o">.</span><span
class="n">description</span><span class="p">,</span> <span
class="bp">self</span><span class="o">.</span><span class="n">price</span>
+ <span class="p">)</span>
+
+<span class="k">class</span> <span class="nc">OrderItem</span><span
class="p">(</span><span class="n">Base</span><span class="p">):</span>
+ <span class="n">__tablename__</span> <span class="o">=</span> <span
class="s">'orderitem'</span>
+ <span class="n">order_id</span> <span class="o">=</span> <span
class="n">Column</span><span class="p">(</span><span
class="n">Integer</span><span class="p">,</span> <span
class="n">ForeignKey</span><span class="p">(</span><span
class="s">'order.order_id'</span><span class="p">),</span> <span
class="n">primary_key</span><span class="o">=</span><span
class="bp">True</span><span class="p">)</span>
+ <span class="n">item_id</span> <span class="o">=</span> <span
class="n">Column</span><span class="p">(</span><span
class="n">Integer</span><span class="p">,</span> <span
class="n">ForeignKey</span><span class="p">(</span><span
class="s">'item.item_id'</span><span class="p">),</span> <span
class="n">primary_key</span><span class="o">=</span><span
class="bp">True</span><span class="p">)</span>
+ <span class="n">price</span> <span class="o">=</span> <span
class="n">Column</span><span class="p">(</span><span
class="n">Float</span><span class="p">,</span> <span
class="n">nullable</span><span class="o">=</span><span
class="bp">False</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span
class="n">item</span><span class="p">,</span> <span class="n">price</span><span
class="o">=</span><span class="bp">None</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span
class="n">item</span> <span class="o">=</span> <span class="n">item</span>
+ <span class="bp">self</span><span class="o">.</span><span
class="n">price</span> <span class="o">=</span> <span class="n">price</span>
<span class="ow">or</span> <span class="n">item</span><span
class="o">.</span><span class="n">price</span>
+ <span class="n">item</span> <span class="o">=</span> <span
class="n">relationship</span><span class="p">(</span><span
class="n">Item</span><span class="p">,</span> <span class="n">lazy</span><span
class="o">=</span><span class="s">'joined'</span><span
class="p">)</span>
+
+<span class="k">if</span> <span class="n">__name__</span> <span
class="o">==</span> <span class="s">'__main__'</span><span
class="p">:</span>
+ <span class="n">engine</span> <span class="o">=</span> <span
class="n">create_engine</span><span class="p">(</span><span
class="s">'sqlite://'</span><span class="p">)</span>
+ <span class="n">Base</span><span class="o">.</span><span
class="n">metadata</span><span class="o">.</span><span
class="n">create_all</span><span class="p">(</span><span
class="n">engine</span><span class="p">)</span>
+
+ <span class="n">session</span> <span class="o">=</span> <span
class="n">Session</span><span class="p">(</span><span
class="n">engine</span><span class="p">)</span>
+
+ <span class="c"># create catalog</span>
+ <span class="n">tshirt</span><span class="p">,</span> <span
class="n">mug</span><span class="p">,</span> <span class="n">hat</span><span
class="p">,</span> <span class="n">crowbar</span> <span class="o">=</span>
<span class="p">(</span>
+ <span class="n">Item</span><span class="p">(</span><span
class="s">'SA T-Shirt'</span><span class="p">,</span> <span
class="mf">10.99</span><span class="p">),</span>
+ <span class="n">Item</span><span class="p">(</span><span
class="s">'SA Mug'</span><span class="p">,</span> <span
class="mf">6.50</span><span class="p">),</span>
+ <span class="n">Item</span><span class="p">(</span><span
class="s">'SA Hat'</span><span class="p">,</span> <span
class="mf">8.99</span><span class="p">),</span>
+ <span class="n">Item</span><span class="p">(</span><span
class="s">'MySQL Crowbar'</span><span class="p">,</span> <span
class="mf">16.99</span><span class="p">)</span>
+ <span class="p">)</span>
+ <span class="n">session</span><span class="o">.</span><span
class="n">add_all</span><span class="p">([</span><span
class="n">tshirt</span><span class="p">,</span> <span class="n">mug</span><span
class="p">,</span> <span class="n">hat</span><span class="p">,</span> <span
class="n">crowbar</span><span class="p">])</span>
+ <span class="n">session</span><span class="o">.</span><span
class="n">commit</span><span class="p">()</span>
+
+ <span class="c"># create an order</span>
+ <span class="n">order</span> <span class="o">=</span> <span
class="n">Order</span><span class="p">(</span><span class="s">'john
smith'</span><span class="p">)</span>
+
+ <span class="c"># add items via the association proxy.</span>
+ <span class="c"># the OrderItem is created automatically.</span>
+ <span class="n">order</span><span class="o">.</span><span
class="n">items</span><span class="o">.</span><span
class="n">append</span><span class="p">(</span><span class="n">mug</span><span
class="p">)</span>
+ <span class="n">order</span><span class="o">.</span><span
class="n">items</span><span class="o">.</span><span
class="n">append</span><span class="p">(</span><span class="n">hat</span><span
class="p">)</span>
+
+ <span class="c"># add an OrderItem explicitly.</span>
+ <span class="n">order</span><span class="o">.</span><span
class="n">order_items</span><span class="o">.</span><span
class="n">append</span><span class="p">(</span><span
class="n">OrderItem</span><span class="p">(</span><span
class="n">crowbar</span><span class="p">,</span> <span
class="mf">10.99</span><span class="p">))</span>
+
+ <span class="n">session</span><span class="o">.</span><span
class="n">add</span><span class="p">(</span><span class="n">order</span><span
class="p">)</span>
+ <span class="n">session</span><span class="o">.</span><span
class="n">commit</span><span class="p">()</span>
+
+ <span class="c"># query the order, print items</span>
+ <span class="n">order</span> <span class="o">=</span> <span
class="n">session</span><span class="o">.</span><span
class="n">query</span><span class="p">(</span><span class="n">Order</span><span
class="p">)</span><span class="o">.</span><span class="n">filter_by</span><span
class="p">(</span><span class="n">customer_name</span><span
class="o">=</span><span class="s">'john smith'</span><span
class="p">)</span><span class="o">.</span><span class="n">one</span><span
class="p">()</span>
+
+ <span class="c"># print items based on the OrderItem collection
directly</span>
+ <span class="k">print</span><span class="p">([(</span><span
class="n">assoc</span><span class="o">.</span><span class="n">item</span><span
class="o">.</span><span class="n">description</span><span class="p">,</span>
<span class="n">assoc</span><span class="o">.</span><span
class="n">price</span><span class="p">,</span> <span
class="n">assoc</span><span class="o">.</span><span class="n">item</span><span
class="o">.</span><span class="n">price</span><span class="p">)</span>
+ <span class="k">for</span> <span class="n">assoc</span> <span
class="ow">in</span> <span class="n">order</span><span class="o">.</span><span
class="n">order_items</span><span class="p">])</span>
+
+ <span class="c"># print items based on the "proxied" items
collection</span>
+ <span class="k">print</span><span class="p">([(</span><span
class="n">item</span><span class="o">.</span><span
class="n">description</span><span class="p">,</span> <span
class="n">item</span><span class="o">.</span><span class="n">price</span><span
class="p">)</span>
+ <span class="k">for</span> <span class="n">item</span> <span
class="ow">in</span> <span class="n">order</span><span class="o">.</span><span
class="n">items</span><span class="p">])</span>
+
+ <span class="c"># print customers who bought 'MySQL Crowbar' on
sale</span>
+ <span class="n">orders</span> <span class="o">=</span> <span
class="n">session</span><span class="o">.</span><span
class="n">query</span><span class="p">(</span><span class="n">Order</span><span
class="p">)</span><span class="o">.</span>\
+ <span class="n">join</span><span class="p">(</span><span
class="s">'order_items'</span><span class="p">,</span> <span
class="s">'item'</span><span class="p">)</span><span class="o">.</span>\
+ <span class="nb">filter</span><span
class="p">(</span><span class="n">Item</span><span class="o">.</span><span
class="n">description</span> <span class="o">==</span> <span
class="s">'MySQL Crowbar'</span><span class="p">)</span><span
class="o">.</span>\
+ <span class="nb">filter</span><span
class="p">(</span><span class="n">Item</span><span class="o">.</span><span
class="n">price</span> <span class="o">></span> <span
class="n">OrderItem</span><span class="o">.</span><span
class="n">price</span><span class="p">)</span>
+ <span class="k">print</span><span class="p">([</span><span
class="n">o</span><span class="o">.</span><span class="n">customer_name</span>
<span class="k">for</span> <span class="n">o</span> <span class="ow">in</span>
<span class="n">orders</span><span class="p">])</span></pre></div>
+ </div>
+
+</div>
+
+<div id="docs-bottom-navigation" class="docs-navigation-links">
+
+ <div id="docs-copyright">
+ © <a href="../../../copyright.html">Copyright</a> 2007-2015, the
SQLAlchemy authors and contributors.
+ Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.3.1.
+ </div>
+</div>
+
+</div>
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit