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 <mike...@zzzcomputing.com> +- Jason Kirtland <j...@discorporate.us> +- Gaetan de Menten <gdemen...@gmail.com> +- Diana Clarke <diana.joan.cla...@gmail.com> +- Michael Trier <mtr...@gmail.com> +- Philip Jenvey <pjen...@underboss.org> +- Ants Aasma <ants.aa...@gmail.com> +- Paul Johnston <p...@pajhome.org.uk> +- Jonathan Ellis <jbel...@gmail.com> + +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: mike...@zzzcomputing.com +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:tiger@127.0.0.1:3306/test + oracle oracle://scott:tiger@127.0.0.1:1521 + postgresql postgresql://scott:tiger@127.0.0.1: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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit