summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2011-01-02 14:23:42 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2011-01-02 14:23:42 -0500
commit350aed3fdb9f1e73e69655e53f44ca6a91c196da (patch)
tree3d2a128667b5f6ca6d0b4e1f4865fc98aac6b60b /doc
parent71f92436bdc86f30e2c21d8f5244733601e8c39e (diff)
downloadsqlalchemy-350aed3fdb9f1e73e69655e53f44ca6a91c196da.tar.gz
- whitespace removal bonanza
Diffstat (limited to 'doc')
-rw-r--r--doc/build/builder/builders.py19
-rw-r--r--doc/build/builder/util.py4
-rw-r--r--doc/build/core/connections.rst8
-rw-r--r--doc/build/core/engines.rst6
-rw-r--r--doc/build/core/event.rst14
-rw-r--r--doc/build/core/expression_api.rst32
-rw-r--r--doc/build/core/index.rst5
-rw-r--r--doc/build/core/schema.rst10
-rw-r--r--doc/build/core/tutorial.rst6
-rw-r--r--doc/build/core/types.rst28
-rw-r--r--doc/build/index.rst4
-rw-r--r--doc/build/intro.rst4
-rw-r--r--doc/build/orm/collections.rst10
-rw-r--r--doc/build/orm/extensions/associationproxy.rst2
-rw-r--r--doc/build/orm/extensions/horizontal_shard.rst2
-rw-r--r--doc/build/orm/extensions/mutable.rst2
-rw-r--r--doc/build/orm/index.rst5
-rw-r--r--doc/build/orm/inheritance.rst8
-rw-r--r--doc/build/orm/loading.rst18
-rw-r--r--doc/build/orm/mapper_config.rst56
-rw-r--r--doc/build/orm/relationships.rst38
-rw-r--r--doc/build/orm/session.rst68
-rw-r--r--doc/build/orm/tutorial.rst6
-rw-r--r--doc/build/static/docs.css6
-rw-r--r--doc/build/templates/genindex.mako2
-rw-r--r--doc/build/templates/layout.mako8
26 files changed, 184 insertions, 187 deletions
diff --git a/doc/build/builder/builders.py b/doc/build/builder/builders.py
index b82480ad3..d5feaf85e 100644
--- a/doc/build/builder/builders.py
+++ b/doc/build/builder/builders.py
@@ -14,14 +14,14 @@ from mako.template import Template
class MakoBridge(TemplateBridge):
def init(self, builder, *args, **kw):
self.layout = builder.config.html_context.get('mako_layout', 'html')
-
+
self.lookup = TemplateLookup(directories=builder.config.templates_path,
format_exceptions=True,
imports=[
"from builder import util"
]
)
-
+
def render(self, template, context):
template = template.replace(".html", ".mako")
context['prevtopic'] = context.pop('prev', None)
@@ -30,8 +30,8 @@ class MakoBridge(TemplateBridge):
# sphinx 1.0b2 doesn't seem to be providing _ for some reason...
context.setdefault('_', lambda x:x)
return self.lookup.get_template(template).render_unicode(**context)
-
-
+
+
def render_string(self, template, context):
context['prevtopic'] = context.pop('prev', None)
context['nexttopic'] = context.pop('next', None)
@@ -44,7 +44,7 @@ class MakoBridge(TemplateBridge):
"from builder import util"
]
).render_unicode(**context)
-
+
class StripDocTestFilter(Filter):
def filter(self, lexer, stream):
for ttype, value in stream:
@@ -116,7 +116,7 @@ def _strip_trailing_whitespace(iter_):
buf[-1] = (buf[-1][0], buf[-1][1].rstrip())
for t, v in buf:
yield t, v
-
+
class PopupSQLFormatter(HtmlFormatter):
def _format_lines(self, tokensource):
buf = []
@@ -134,7 +134,7 @@ class PopupSQLFormatter(HtmlFormatter):
yield 1, "<div class='popup_sql'>%s</div>" % re.sub(r'(?:[{stop}|\n]*)$', '', value)
else:
buf.append((ttype, value))
-
+
for t, v in _strip_trailing_whitespace(HtmlFormatter._format_lines(self, iter(buf))):
yield t, v
@@ -148,7 +148,7 @@ class PopupLatexFormatter(LatexFormatter):
continue
else:
yield ttype, value
-
+
def format(self, tokensource, outfile):
LatexFormatter.format(self, self._filter_tokens(tokensource), outfile)
@@ -164,5 +164,4 @@ def setup(app):
app.connect('autodoc-skip-member', autodoc_skip_member)
PygmentsBridge.html_formatter = PopupSQLFormatter
PygmentsBridge.latex_formatter = PopupLatexFormatter
-
- \ No newline at end of file
+
diff --git a/doc/build/builder/util.py b/doc/build/builder/util.py
index dc2e27245..a9dcff001 100644
--- a/doc/build/builder/util.py
+++ b/doc/build/builder/util.py
@@ -6,7 +6,7 @@ def striptags(text):
def go(m):
# .html with no anchor if present, otherwise "#" for top of page
return m.group(1) or '#'
-
+
def strip_toplevel_anchors(text):
return re.compile(r'(\.html)?#[-\w]+-toplevel').sub(go, text)
-
+
diff --git a/doc/build/core/connections.rst b/doc/build/core/connections.rst
index 7591e73e2..7b2e6aa69 100644
--- a/doc/build/core/connections.rst
+++ b/doc/build/core/connections.rst
@@ -22,7 +22,7 @@ Recall from :ref:`engines_toplevel` that an :class:`.Engine` is created via
the :func:`.create_engine` call::
engine = create_engine('mysql://scott:tiger@localhost/test')
-
+
The typical usage of :func:`.create_engine()` is once per particular database
URL, held globally for the lifetime of a single application process. A single
:class:`.Engine` manages many individual DBAPI connections on behalf of the
@@ -89,7 +89,7 @@ If the :class:`.ResultProxy` potentially has rows remaining, it can be
instructed to close out its resources explicitly::
result.close()
-
+
If the :class:`.ResultProxy` has pending rows remaining and is dereferenced by
the application without being closed, Python garbage collection will
ultimately close out the cursor as well as trigger a return of the pooled
@@ -116,7 +116,7 @@ in :ref:`sqlexpression_toplevel`.
.. autoclass:: sqlalchemy.engine.base.ResultProxy
:members:
-
+
.. autoclass:: sqlalchemy.engine.base.RowProxy
:members:
@@ -243,7 +243,7 @@ to use the :meth:`~.Executable.execute` method of
any :class:`.Executable` construct, which is a marker for SQL expression objects
that support execution. The SQL expression object itself references an
:class:`.Engine` or :class:`.Connection` known as the **bind**, which it uses
-in order to provide so-called "implicit" execution services.
+in order to provide so-called "implicit" execution services.
Given a table as below::
diff --git a/doc/build/core/engines.rst b/doc/build/core/engines.rst
index dbc7dcc45..0b5ce345d 100644
--- a/doc/build/core/engines.rst
+++ b/doc/build/core/engines.rst
@@ -46,9 +46,9 @@ SQLAlchemy dialect always requires that an appropriate DBAPI driver is installed
The table below summarizes the state of DBAPI support in SQLAlchemy 0.7. The values
translate as:
-* yes / Python platform - The SQLAlchemy dialect is mostly or fully operational on the target platform.
+* yes / Python platform - The SQLAlchemy dialect is mostly or fully operational on the target platform.
* yes / OS platform - The DBAPI supports that platform.
-* no / Python platform - The DBAPI does not support that platform, or there is no SQLAlchemy dialect support.
+* no / Python platform - The DBAPI does not support that platform, or there is no SQLAlchemy dialect support.
* no / OS platform - The DBAPI does not support that platform.
* partial - the DBAPI is partially usable on the target platform but has major unresolved issues.
* development - a development version of the dialect exists, but is not yet usable.
@@ -280,7 +280,7 @@ namespace of SA loggers that can be turned on is as follows:
* ``sqlalchemy.engine`` - controls SQL echoing. set to ``logging.INFO`` for SQL query output, ``logging.DEBUG`` for query + result set output.
* ``sqlalchemy.dialects`` - controls custom logging for SQL dialects. See the documentation of individual dialects for details.
* ``sqlalchemy.pool`` - controls connection pool logging. set to ``logging.INFO`` or lower to log connection pool checkouts/checkins.
-* ``sqlalchemy.orm`` - controls logging of various ORM functions. set to ``logging.INFO`` for information on mapper configurations.
+* ``sqlalchemy.orm`` - controls logging of various ORM functions. set to ``logging.INFO`` for information on mapper configurations.
For example, to log SQL queries using Python logging instead of the ``echo=True`` flag::
diff --git a/doc/build/core/event.rst b/doc/build/core/event.rst
index f1a428d8c..86cc7d968 100644
--- a/doc/build/core/event.rst
+++ b/doc/build/core/event.rst
@@ -24,10 +24,10 @@ and that a user-defined listener function should receive two positional argument
from sqlalchemy.event import listen
from sqlalchemy.pool import Pool
-
+
def my_on_connect(dbapi_con, connection_record):
print "New DBAPI connection:", dbapi_con
-
+
listen(Pool, 'connect', my_on_connect)
Targets
@@ -43,13 +43,13 @@ classes and objects::
from sqlalchemy import create_engine
from sqlalchemy.engine import Engine
import psycopg2
-
+
def connect():
return psycopg2.connect(username='ed', host='127.0.0.1', dbname='test')
my_pool = QueuePool(connect)
my_engine = create_engine('postgresql://ed@localhost/test')
-
+
# associate listener with all instances of Pool
listen(Pool, 'connect', my_on_connect)
@@ -73,9 +73,9 @@ which modifies the subsequent handling. By default, no listener ever requires
def validate_phone(target, value, oldvalue, initiator):
"""Strip non-numeric characters from a phone number"""
-
+
return re.sub(r'(?![0-9])', '', value)
-
+
# setup listener on UserContact.phone attribute, instructing
# it to use the return value
listen(UserContact.phone, 'set', validate_phone, retval=True)
@@ -89,7 +89,7 @@ Both SQLAlchemy Core and SQLAlchemy ORM feature a wide variety of event hooks:
:ref:`core_event_toplevel` and include event hooks specific to
connection pool lifecycle, SQL statement execution,
transaction lifecycle, and schema creation and teardown.
-
+
* **ORM Events** - these are described in
:ref:`orm_event_toplevel`, and include event hooks specific to
class and attribute instrumentation, object initialization
diff --git a/doc/build/core/expression_api.rst b/doc/build/core/expression_api.rst
index 1b4a35f84..e907b2535 100644
--- a/doc/build/core/expression_api.rst
+++ b/doc/build/core/expression_api.rst
@@ -46,11 +46,11 @@ The expression package uses functions to construct SQL expressions. The return
.. autofunction:: extract
.. attribute:: func
-
+
Generate SQL function expressions.
-
+
``func`` is a special object instance which generates SQL functions based on name-based attributes, e.g.::
-
+
>>> print func.count(1)
count(:param_1)
@@ -58,29 +58,29 @@ The expression package uses functions to construct SQL expressions. The return
SQLAlchemy, it will be rendered exactly as is. For common SQL functions
which SQLAlchemy is aware of, the name may be interpreted as a *generic
function* which will be compiled appropriately to the target database::
-
+
>>> print func.current_timestamp()
CURRENT_TIMESTAMP
-
+
To call functions which are present in dot-separated packages, specify them in the same manner::
-
+
>>> print func.stats.yield_curve(5, 10)
stats.yield_curve(:yield_curve_1, :yield_curve_2)
-
+
SQLAlchemy can be made aware of the return type of functions to enable
type-specific lexical and result-based behavior. For example, to ensure
that a string-based function returns a Unicode value and is similarly
treated as a string in expressions, specify
:class:`~sqlalchemy.types.Unicode` as the type:
-
+
>>> print func.my_string(u'hi', type_=Unicode) + ' ' + \
... func.my_string(u'there', type_=Unicode)
my_string(:my_string_1) || :my_string_2 || my_string(:my_string_3)
-
+
Functions which are interpreted as "generic" functions know how to
calculate their return type automatically. For a listing of known generic
functions, see :ref:`generic_functions`.
-
+
.. autofunction:: insert
.. autofunction:: intersect
@@ -179,7 +179,7 @@ Classes
.. autoclass:: Function
:members:
:show-inheritance:
-
+
.. autoclass:: FromClause
:members:
:show-inheritance:
@@ -220,18 +220,18 @@ Generic Functions
SQL functions which are known to SQLAlchemy with regards to database-specific
rendering, return types and argument behavior. Generic functions are invoked
like all SQL functions, using the :attr:`func` attribute::
-
+
select([func.count()]).select_from(sometable)
-
+
Note that any name not known to :attr:`func` generates the function name as is
- there is no restriction on what SQL functions can be called, known or
unknown to SQLAlchemy, built-in or user defined. The section here only
describes those functions where SQLAlchemy already knows what argument and
return types are in use.
-
+
.. automodule:: sqlalchemy.sql.functions
:members:
:undoc-members:
:show-inheritance:
-
-
+
+
diff --git a/doc/build/core/index.rst b/doc/build/core/index.rst
index 6af349322..780016bae 100644
--- a/doc/build/core/index.rst
+++ b/doc/build/core/index.rst
@@ -5,7 +5,7 @@ SQLAlchemy Core
.. toctree::
:maxdepth: 2
-
+
tutorial
expression_api
engines
@@ -19,5 +19,4 @@ SQLAlchemy Core
compiler
serializer
interfaces
-
- \ No newline at end of file
+
diff --git a/doc/build/core/schema.rst b/doc/build/core/schema.rst
index c1f99feeb..3caced3ae 100644
--- a/doc/build/core/schema.rst
+++ b/doc/build/core/schema.rst
@@ -1217,9 +1217,9 @@ will take over the job of issuing DDL for the constraint. Additionally, the
constraint will be added via ALTER:
.. sourcecode:: python+sql
-
+
from sqlalchemy import event
-
+
event.listen(
users,
"after_create",
@@ -1251,7 +1251,7 @@ parameter ``dialect``, which is the string name of a dialect or a tuple of such,
which will limit the execution of the item to just those dialects. It also
accepts a ``callable_`` parameter which may reference a Python callable which will
be invoked upon event reception, returning ``True`` or ``False`` indicating if
-the event should proceed.
+the event should proceed.
If our :class:`~sqlalchemy.schema.CheckConstraint` was only supported by
Postgresql and not other databases, we could limit its usage to just that dialect::
@@ -1268,7 +1268,7 @@ Postgresql and not other databases, we could limit its usage to just that dialec
)
Or to any set of dialects::
-
+
event.listen(
users,
"after_create",
@@ -1332,7 +1332,7 @@ Custom DDL phrases are most easily achieved using the
other DDL elements except it accepts a string which is the text to be emitted:
.. sourcecode:: python+sql
-
+
event.listen(
metadata,
"after_create",
diff --git a/doc/build/core/tutorial.rst b/doc/build/core/tutorial.rst
index b7d5ba272..543d57ae2 100644
--- a/doc/build/core/tutorial.rst
+++ b/doc/build/core/tutorial.rst
@@ -1078,7 +1078,7 @@ Finally, we're back to INSERT for some more detail. The :func:`~sqlalchemy.sql.e
# insert from a function
users.insert().values(id=12, name=func.upper('jack'))
-
+
# insert from a concatenation expression
addresses.insert().values(email_address = name + '@' + host)
@@ -1088,7 +1088,7 @@ Finally, we're back to INSERT for some more detail. The :func:`~sqlalchemy.sql.e
users.insert().values(name=func.upper('jack')),
fullname='Jack Jones'
)
-
+
:func:`~sqlalchemy.sql.expression.bindparam` constructs can be passed, however the names of the table's columns are reserved for the "automatic" generation of bind names::
users.insert().values(id=bindparam('_id'), name=bindaparam('_name'))
@@ -1102,7 +1102,7 @@ Finally, we're back to INSERT for some more detail. The :func:`~sqlalchemy.sql.e
{'_id':3, '_name':'name3'},
]
)
-
+
Updates work a lot like INSERTS, except there is an additional WHERE clause that can be specified:
.. sourcecode:: pycon+sql
diff --git a/doc/build/core/types.rst b/doc/build/core/types.rst
index 47bbd87d7..d2a56e8e9 100644
--- a/doc/build/core/types.rst
+++ b/doc/build/core/types.rst
@@ -274,17 +274,17 @@ many decimal places. Here's a recipe that rounds them down::
from sqlalchemy.types import TypeDecorator, Numeric
from decimal import Decimal
-
+
class SafeNumeric(TypeDecorator):
"""Adds quantization to Numeric."""
-
+
impl = Numeric
-
+
def __init__(self, *arg, **kw):
TypeDecorator.__init__(self, *arg, **kw)
self.quantize_int = -(self.impl.precision - self.impl.scale)
self.quantize = Decimal(10) ** self.quantize_int
-
+
def process_bind_param(self, value, dialect):
if isinstance(value, Decimal) and \
value.as_tuple()[2] < self.quantize_int:
@@ -305,10 +305,10 @@ binary in CHAR(16) if desired::
class GUID(TypeDecorator):
"""Platform-independent GUID type.
-
+
Uses Postgresql's UUID type, otherwise uses
CHAR(32), storing as stringified hex values.
-
+
"""
impl = CHAR
@@ -348,11 +348,11 @@ to/from JSON. Can be modified to use Python's builtin json encoder::
class JSONEncodedDict(TypeDecorator):
"""Represents an immutable structure as a json-encoded string.
-
+
Usage::
-
+
JSONEncodedDict(255)
-
+
"""
impl = VARCHAR
@@ -377,7 +377,7 @@ changes, and combine this using the ``sqlalchemy.ext.mutable`` extension
described in :ref:`mutable_toplevel`::
from sqlalchemy.ext.mutable import Mutable
-
+
class MutationDict(Mutable, dict):
@classmethod
def coerce(cls, key, value):
@@ -385,15 +385,15 @@ described in :ref:`mutable_toplevel`::
if not isinstance(value, MutationDict):
if isinstance(value, dict):
return MutationDict(value)
-
+
# this call will raise ValueError
return Mutable.coerce(key, value)
else:
return value
-
+
def __setitem__(self, key, value):
"""Detect dictionary set events and emit change events."""
-
+
dict.__setitem__(self, key, value)
self.change()
@@ -402,7 +402,7 @@ described in :ref:`mutable_toplevel`::
dict.__delitem__(self, key)
self.change()
-
+
# additional dict methods would be overridden here
The new dictionary type can be associated with JSONEncodedDict using
diff --git a/doc/build/index.rst b/doc/build/index.rst
index 2d75a5c08..e6442efd0 100644
--- a/doc/build/index.rst
+++ b/doc/build/index.rst
@@ -3,12 +3,12 @@ Table of Contents
.. toctree::
:maxdepth: 2
-
+
intro
orm/index
core/index
dialects/index
-
+
Indices and tables
------------------
diff --git a/doc/build/intro.rst b/doc/build/intro.rst
index b679dca3e..d3409cec3 100644
--- a/doc/build/intro.rst
+++ b/doc/build/intro.rst
@@ -28,7 +28,7 @@ queries.
Documentation Overview
======================
-The documentation is separated into three sections: :ref:`orm_toplevel`, :ref:`core_toplevel`, and :ref:`dialect_toplevel`.
+The documentation is separated into three sections: :ref:`orm_toplevel`, :ref:`core_toplevel`, and :ref:`dialect_toplevel`.
In :ref:`orm_toplevel`, the Object Relational Mapper is introduced and fully
described. New users should begin with the :ref:`ormtutorial_toplevel`. If you
@@ -71,7 +71,7 @@ this from the command-line:
.. sourcecode:: none
# easy_install SQLAlchemy
-
+
Or with pip:
.. sourcecode:: none
diff --git a/doc/build/orm/collections.rst b/doc/build/orm/collections.rst
index 7f585fc50..98de8e205 100644
--- a/doc/build/orm/collections.rst
+++ b/doc/build/orm/collections.rst
@@ -5,7 +5,7 @@
Collection Configuration and Techniques
=======================================
-The :func:`.relationship` function defines a linkage between two classes.
+The :func:`.relationship` function defines a linkage between two classes.
When the linkage defines a one-to-many or many-to-many relationship, it's
represented as a Python collection when objects are loaded and manipulated.
This section presents additional information about collection configuration
@@ -335,21 +335,21 @@ on :class:`.MappedCollection` are already instrumented - calling them
from within an already instrumented call can cause events to be fired off
repeatedly, or inappropriately, leading to internal state corruption in
rare cases::
-
+
from sqlalchemy.orm.collections import MappedCollection,\
collection
class MyMappedCollection(MappedCollection):
"""Use @internally_instrumented when your methods
call down to already-instrumented methods.
-
+
"""
-
+
@collection.internally_instrumented
def __setitem__(self, key, value, _sa_initiator=None):
# do something with key, value
super(MyMappedCollection, self).__setitem__(key, value, _sa_initiator)
-
+
@collection.internally_instrumented
def __delitem__(self, key, _sa_initiator=None):
# do something with key
diff --git a/doc/build/orm/extensions/associationproxy.rst b/doc/build/orm/extensions/associationproxy.rst
index 4a7ce5dbf..c0b99cc5c 100644
--- a/doc/build/orm/extensions/associationproxy.rst
+++ b/doc/build/orm/extensions/associationproxy.rst
@@ -287,7 +287,7 @@ of the ``Holding`` while also giving access to ``.shares``::
session.add(broker)
session.commit()
-
+
# lets take a peek at that holdings_table after committing changes to the db
print list(holdings_table.select().execute())
# [(1, 'ZZK', 10), (1, 'JEK', 123), (1, 'STEPZ', 123)]
diff --git a/doc/build/orm/extensions/horizontal_shard.rst b/doc/build/orm/extensions/horizontal_shard.rst
index 67cd707d8..deb97a74c 100644
--- a/doc/build/orm/extensions/horizontal_shard.rst
+++ b/doc/build/orm/extensions/horizontal_shard.rst
@@ -8,7 +8,7 @@ API Documentation
.. autoclass:: ShardedSession
:members:
-
+
.. autoclass:: ShardedQuery
:members:
diff --git a/doc/build/orm/extensions/mutable.rst b/doc/build/orm/extensions/mutable.rst
index 9844f9b09..0b15e7a60 100644
--- a/doc/build/orm/extensions/mutable.rst
+++ b/doc/build/orm/extensions/mutable.rst
@@ -10,7 +10,7 @@ API Reference
.. autoclass:: Mutable
:members:
-
+
.. autoclass:: MutableComposite
:members:
diff --git a/doc/build/orm/index.rst b/doc/build/orm/index.rst
index af6b0c365..b17fe7547 100644
--- a/doc/build/orm/index.rst
+++ b/doc/build/orm/index.rst
@@ -5,7 +5,7 @@ SQLAlchemy ORM
.. toctree::
:maxdepth: 2
-
+
tutorial
mapper_config
relationships
@@ -19,5 +19,4 @@ SQLAlchemy ORM
extensions/index
examples
interfaces
-
- \ No newline at end of file
+
diff --git a/doc/build/orm/inheritance.rst b/doc/build/orm/inheritance.rst
index 65bcd06f9..ff932f0f3 100644
--- a/doc/build/orm/inheritance.rst
+++ b/doc/build/orm/inheritance.rst
@@ -261,7 +261,7 @@ what's specified in the :meth:`.Session.query`, :meth:`.Query.filter`, or
:meth:`.Query.select_from` methods::
session.query(Manager.manager_data).select_from(manager)
-
+
session.query(engineer.c.id).filter(engineer.c.engineer_info==manager.c.manager_data)
Creating Joins to Specific Subtypes
@@ -530,17 +530,17 @@ to the parent:
with_polymorphic=('*', pjoin),
polymorphic_on=pjoin.c.type,
polymorphic_identity='employee')
-
+
mapper(Manager, managers_table,
inherits=employee_mapper,
concrete=True,
polymorphic_identity='manager')
-
+
mapper(Engineer, engineers_table,
inherits=employee_mapper,
concrete=True,
polymorphic_identity='engineer')
-
+
mapper(Company, companies, properties={
'employees': relationship(Employee)
})
diff --git a/doc/build/orm/loading.rst b/doc/build/orm/loading.rst
index afe4ff6b6..e2fc9f6dd 100644
--- a/doc/build/orm/loading.rst
+++ b/doc/build/orm/loading.rst
@@ -7,7 +7,7 @@ Relationship Loading Techniques
A big part of SQLAlchemy is providing a wide range of control over how related objects get loaded when querying. This behavior
can be configured at mapper construction time using the ``lazy`` parameter to the :func:`.relationship` function,
-as well as by using options with the :class:`.Query` object.
+as well as by using options with the :class:`.Query` object.
Using Loader Strategies: Lazy Loading, Eager Loading
----------------------------------------------------
@@ -59,7 +59,7 @@ additional SQL statement for each collection requested, aggregated across all
parent objects:
.. sourcecode:: python+sql
-
+
{sql}>>>jack = session.query(User).options(subqueryload('addresses')).filter_by(name='jack').all()
SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname,
users.password AS users_password
@@ -187,7 +187,7 @@ references a scalar many-to-one reference.
* When using the default lazy loading, if you load 100 objects, and then access a collection on each of
them, a total of 101 SQL statements will be emitted, although each statement will typically be a
simple SELECT without any joins.
-
+
* When using joined loading, the load of 100 objects and their collections will emit only one SQL
statement. However, the
total number of rows fetched will be equal to the sum of the size of all the collections, plus one
@@ -197,16 +197,16 @@ references a scalar many-to-one reference.
exceptions) will transmit the full data of each parent over the wire to the client connection in
any case. Therefore joined eager loading only makes sense when the size of the collections are
relatively small. The LEFT OUTER JOIN can also be performance intensive compared to an INNER join.
-
+
* When using subquery loading, the load of 100 objects will emit two SQL statements. The second
statement will fetch a total number of rows equal to the sum of the size of all collections. An
INNER JOIN is used, and a minimum of parent columns are requested, only the primary keys. So a
subquery load makes sense when the collections are larger.
-
+
* When multiple levels of depth are used with joined or subquery loading, loading collections-within-
collections will multiply the total number of rows fetched in a cartesian fashion. Both forms
of eager loading always join from the original parent class.
-
+
* Many to One Reference
* When using the default lazy loading, a load of 100 objects will like in the case of the collection
@@ -216,15 +216,15 @@ references a scalar many-to-one reference.
if the collection of objects references a relatively small set of target objects, or the full set
of possible target objects have already been loaded into the session and are strongly referenced,
using the default of `lazy='select'` is by far the most efficient way to go.
-
+
* When using joined loading, the load of 100 objects will emit only one SQL statement. The join
- will be a LEFT OUTER JOIN, and the total number of rows will be equal to 100 in all cases.
+ will be a LEFT OUTER JOIN, and the total number of rows will be equal to 100 in all cases.
If you know that each parent definitely has a child (i.e. the foreign
key reference is NOT NULL), the joined load can be configured with ``innerjoin=True``, which is
usually specified within the :func:`~sqlalchemy.orm.relationship`. For a load of objects where
there are many possible target references which may have not been loaded already, joined loading
with an INNER JOIN is extremely efficient.
-
+
* Subquery loading will issue a second load for all the child objects, so for a load of 100 objects
there would be two SQL statements emitted. There's probably not much advantage here over
joined loading, however, except perhaps that subquery loading can use an INNER JOIN in all cases
diff --git a/doc/build/orm/mapper_config.rst b/doc/build/orm/mapper_config.rst
index 4c57b8c45..7c0641147 100644
--- a/doc/build/orm/mapper_config.rst
+++ b/doc/build/orm/mapper_config.rst
@@ -15,7 +15,7 @@ Note that all patterns here apply both to the usage of explicit
takes a form such as::
mapper(User, users_table, primary_key=[users_table.c.id])
-
+
Would translate into declarative as::
class User(Base):
@@ -29,9 +29,9 @@ with the class definition. These are usable as is within ``__mapper_args__``::
class User(Base):
__tablename__ = 'users'
-
+
id = Column(Integer)
-
+
__mapper_args__ = {
'primary_key':[id]
}
@@ -52,7 +52,7 @@ use the ``include_properties`` or ``exclude_properties`` arguments. For
example::
mapper(User, users_table, include_properties=['user_id', 'user_name'])
-
+
...will map the ``User`` class to the ``users_table`` table, only including
the "user_id" and "user_name" columns - the rest are not refererenced.
Similarly::
@@ -106,7 +106,7 @@ using the desired attribute name in the class definition::
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
-
+
class User(Base):
__tablename__ = 'user'
id = Column('user_id', Integer, primary_key=True)
@@ -130,7 +130,7 @@ key relationship or join condition into the same mapped attribute, put them
together using a list, as below where we map to a :func:`~.expression.join`::
from sqlalchemy.sql import join
-
+
# join users and addresses
usersaddresses = join(users_table, addresses_table, \
users_table.c.user_id == addresses_table.c.user_id)
@@ -152,21 +152,21 @@ usually invoked implicitly for each mapped :class:`.Column`. Explicit usage
looks like::
from sqlalchemy.orm import mapper, column_property
-
+
mapper(User, users, properties={
'name':column_property(users.c.name, active_history=True)
})
or with declarative::
-
+
class User(Base):
__tablename__ = 'users'
-
+
id = Column(Integer, primary_key=True)
name = column_property(Column(String(50)), active_history=True)
Further examples of :func:`.column_property` are at :ref:`mapper_sql_expressions`.
-
+
.. autofunction:: column_property
.. _deferred:
@@ -204,7 +204,7 @@ With declarative, :class:`.Column` objects can be declared directly inside of :f
class Book(Base):
__tablename__ = 'books'
-
+
book_id = Column(Integer, primary_key=True)
title = Column(String(200), nullable=False)
summary = Column(String(2000))
@@ -273,7 +273,7 @@ scalar-returning
used. Unlike older versions of SQLAlchemy, there is no :func:`~.sql.expression.label` requirement::
from sqlalchemy.orm import column_property
-
+
mapper(User, users_table, properties={
'fullname': column_property(
users_table.c.firstname + " " + users_table.c.lastname
@@ -284,7 +284,7 @@ Correlated subqueries may be used as well::
from sqlalchemy.orm import column_property
from sqlalchemy import select, func
-
+
mapper(User, users_table, properties={
'address_count': column_property(
select([func.count(addresses_table.c.address_id)]).\
@@ -305,7 +305,7 @@ loaded::
@property
def fullname(self):
return self.firstname + " " + self.lastname
-
+
To invoke a SQL statement from an instance that's already been loaded, the
session associated with the instance can be acquired using
:func:`~.session.object_session` which will provide the appropriate
@@ -313,7 +313,7 @@ transactional context from which to emit a statement::
from sqlalchemy.orm import object_session
from sqlalchemy import select, func
-
+
class User(object):
@property
def address_count(self):
@@ -343,9 +343,9 @@ attribute extensions, are only called by normal userland code; they are not
issued when the ORM is populating the object.
.. sourcecode:: python+sql
-
+
from sqlalchemy.orm import validates
-
+
addresses_table = Table('addresses', metadata,
Column('id', Integer, primary_key=True),
Column('email', String)
@@ -383,11 +383,11 @@ plain descriptor, and to have it read/write from a mapped attribute with a
different name. Below we illustrate this using Python 2.6-style properties::
class EmailAddress(object):
-
+
@property
def email(self):
return self._email
-
+
@email.setter
def email(self, email):
self._email = email
@@ -456,7 +456,7 @@ do case-insensitive comparison::
from sqlalchemy.orm.properties import ColumnProperty
from sqlalchemy.sql import func
-
+
class MyComparator(ColumnProperty.Comparator):
def __eq__(self, other):
return func.lower(self.__clause_element__()) == func.lower(other)
@@ -496,13 +496,13 @@ class you provide.
As of SQLAlchemy 0.7, composites are implemented as a simple wrapper using
the :ref:`hybrids_toplevel` feature. Note that composites no longer
"conceal" the underlying colunm based attributes, or support in-place
- mutation.
+ mutation.
-A simple example represents pairs of columns as a "Point" object.
+A simple example represents pairs of columns as a "Point" object.
Starting with a table that represents two points as x1/y1 and x2/y2::
from sqlalchemy import Table, Column
-
+
vertices = Table('vertices', metadata,
Column('id', Integer, primary_key=True),
Column('x1', Integer),
@@ -597,7 +597,7 @@ passed in to a mapper as the table.
from sqlalchemy.orm import mapper
from sqlalchemy.sql import join
-
+
class AddressUser(object):
pass
@@ -614,7 +614,7 @@ Note that the list of columns is equivalent to the usage of :func:`.column_prope
with multiple columns::
from sqlalchemy.orm import mapper, column_property
-
+
mapper(AddressUser, j, properties={
'user_id': column_property(users_table.c.user_id, addresses_table.c.user_id)
})
@@ -624,12 +624,12 @@ to multiple columns, since the declarative class parser won't recognize a plain
list of columns::
from sqlalchemy.ext.declarative import declarative_base
-
+
Base = declarative_base()
-
+
class AddressUser(Base):
__table__ = j
-
+
user_id = column_property(users_table.c.user_id, addresses_table.c.user_id)
A second example::
diff --git a/doc/build/orm/relationships.rst b/doc/build/orm/relationships.rst
index f9337a5f6..a4ac63ee7 100644
--- a/doc/build/orm/relationships.rst
+++ b/doc/build/orm/relationships.rst
@@ -63,20 +63,20 @@ To establish a bi-directional relationship in one-to-many, where the "reverse" s
``Child`` will get a ``parent`` attribute with many-to-one semantics.
Declarative::
-
+
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
-
+
class Parent(Base):
__tablename__ = 'parent'
id = Column(Integer, primary_key=True)
children = relationship("Child", backref="parent")
-
+
class Child(Base):
__tablename__ = 'child'
id = Column(Integer, primary_key=True)
parent_id = Column(Integer, ForeignKey('parent.id'))
-
+
Many To One
~~~~~~~~~~~~
@@ -125,7 +125,7 @@ Declarative::
id = Column(Integer, primary_key=True)
child_id = Column(Integer, ForeignKey('child.id'))
child = relationship("Child", backref="parents")
-
+
class Child(Base):
__tablename__ = 'child'
id = Column(Integer, primary_key=True)
@@ -150,14 +150,14 @@ of the relationship. To convert one-to-many into one-to-one::
mapper(Parent, parent_table, properties={
'child': relationship(Child, uselist=False, backref='parent')
})
-
+
mapper(Child, child_table)
Or to turn a one-to-many backref into one-to-one, use the :func:`.backref` function
to provide arguments for the reverse side::
-
+
from sqlalchemy.orm import backref
-
+
parent_table = Table('parent', metadata,
Column('id', Integer, primary_key=True),
Column('child_id', Integer, ForeignKey('child.id'))
@@ -183,11 +183,11 @@ The second example above as declarative::
id = Column(Integer, primary_key=True)
child_id = Column(Integer, ForeignKey('child.id'))
child = relationship("Child", backref=backref("parent", uselist=False))
-
+
class Child(Base):
__tablename__ = 'child'
id = Column(Integer, primary_key=True)
-
+
Many To Many
~~~~~~~~~~~~~
@@ -238,18 +238,18 @@ plain schematic form::
Column('left_id', Integer, ForeignKey('left.id')),
Column('right_id', Integer, ForeignKey('right.id'))
)
-
+
class Parent(Base):
__tablename__ = 'left'
id = Column(Integer, primary_key=True)
children = relationship("Child",
secondary=association_table,
backref="parents")
-
+
class Child(Base):
__tablename__ = 'right'
id = Column(Integer, primary_key=True)
-
+
.. _association_pattern:
Association Object
@@ -313,16 +313,16 @@ Declarative::
left_id = Column(Integer, ForeignKey('left.id'), primary_key=True)
right_id = Column(Integer, ForeignKey('right.id'), primary_key=True)
child = relationship("Child", backref="parent_assocs")
-
+
class Parent(Base):
__tablename__ = 'left'
id = Column(Integer, primary_key=True)
children = relationship(Association, backref="parent")
-
+
class Child(Base):
__tablename__ = 'right'
id = Column(Integer, primary_key=True)
-
+
Working with the association pattern in its direct form requires that child
objects are associated with an association instance before being appended to
the parent; similarly, access from parent to child goes through the
@@ -442,7 +442,7 @@ when the collection is only one column)::
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
-
+
class Node(Base):
__tablename__ = 'nodes'
id = Column(Integer, primary_key=True)
@@ -451,7 +451,7 @@ when the collection is only one column)::
children = relationship("Node",
backref=backref('parent', remote_side=id)
)
-
+
There are several examples included with SQLAlchemy illustrating
self-referential strategies; these include :ref:`examples_adjacencylist` and
:ref:`examples_xmlpersistence`.
@@ -761,7 +761,7 @@ A typical mutable primary key setup might look like:
# passive_updates=False *only* needed if the database
# does not implement ON UPDATE CASCADE
-
+
mapper(User, users, properties={
'addresses': relationship(Address, passive_updates=False)
})
diff --git a/doc/build/orm/session.rst b/doc/build/orm/session.rst
index d08ce5f5a..7e0c8bb83 100644
--- a/doc/build/orm/session.rst
+++ b/doc/build/orm/session.rst
@@ -91,10 +91,10 @@ to acquire connection resources. This association can
be set up as in the example above, using the ``bind`` argument. You
can also associate a :class:`.Engine` with an existing :func:`.sessionmaker`
using the :meth:`.sessionmaker.configure` method::
-
+
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
-
+
# configure Session class with desired options
Session = sessionmaker()
@@ -111,7 +111,7 @@ you can also associate individual :class:`.Session` objects with an :class:`.Eng
on each invocation::
session = Session(bind=engine)
-
+
...or directly with a :class:`.Connection`::
conn = engine.connect()
@@ -167,12 +167,12 @@ Frequently Asked Questions
that point on your other modules say "from mypackage import Session". That
way, everyone else just uses :class:`.Session()`,
and the configuration of that session is controlled by that central point.
-
+
If your application starts up, does imports, but does not know what
database it's going to be connecting to, you can bind the
:class:`.Session` at the "class" level to the
engine later on, using ``configure()``.
-
+
In the examples in this section, we will frequently show the
:func:`.sessionmaker` being created right above the line where we actually
invoke :class:`~sqlalchemy.orm.session.Session()`. But that's just for
@@ -189,7 +189,7 @@ Frequently Asked Questions
then remains in use for the lifespan of a particular database
conversation, which includes not just the initial loading of objects but
throughout the whole usage of those instances.
-
+
Objects become detached if their owning session is discarded. They are
still functional in the detached state if the user has ensured that their
state has not been expired before detachment, but they will not be able to
@@ -197,14 +197,14 @@ Frequently Asked Questions
to consider persisted objects as an extension of the state of a particular
:class:`.Session`, and to keep that session around until all referenced
objects have been discarded.
-
+
An exception to this is when objects are placed in caches or otherwise
shared among threads or processes, in which case their detached state can
be stored, transmitted, or shared. However, the state of detached objects
should still be transferred back into a new :class:`.Session` using
:meth:`.Session.add` or :meth:`.Session.merge` before working with the
object (or in the case of merge, its state) again.
-
+
It is also very common that a :class:`.Session` as well as its associated
objects are only referenced by a single thread. Sharing objects between
threads is most safely accomplished by sharing their state among multiple
@@ -212,7 +212,7 @@ Frequently Asked Questions
:class:`.Session` per thread, :meth:`.Session.merge` to transfer state
between threads. This pattern is not a strict requirement by any means,
but it has the least chance of introducing concurrency issues.
-
+
To help with the recommended :class:`.Session` -per-thread,
:class:`.Session` -per-set-of-objects patterns, the
:func:`.scoped_session` function is provided which produces a
@@ -233,10 +233,10 @@ Frequently Asked Questions
map and see that the object is already there. It's only when you say
``query.get({some primary key})`` that the
:class:`~sqlalchemy.orm.session.Session` doesn't have to issue a query.
-
+
Additionally, the Session stores object instances using a weak reference
by default. This also defeats the purpose of using the Session as a cache.
-
+
The :class:`.Session` is not designed to be a
global object from which everyone consults as a "registry" of objects.
That's more the job of a **second level cache**. SQLAlchemy provides
@@ -278,7 +278,7 @@ Frequently Asked Questions
sharing the session with those threads, but you also will have implemented
a proper locking scheme (or your graphical framework does) so that those
threads do not collide.
-
+
A multithreaded application is usually going to want to make usage of
:func:`.scoped_session` to transparently manage sessions per thread.
More on this at :ref:`unitofwork_contextual`.
@@ -416,33 +416,33 @@ Merge Tips
:meth:`~.Session.merge` is an extremely useful method for many purposes. However,
it deals with the intricate border between objects that are transient/detached and
-those that are persistent, as well as the automated transferrence of state.
+those that are persistent, as well as the automated transferrence of state.
The wide variety of scenarios that can present themselves here often require a
more careful approach to the state of objects. Common problems with merge usually involve
-some unexpected state regarding the object being passed to :meth:`~.Session.merge`.
+some unexpected state regarding the object being passed to :meth:`~.Session.merge`.
Lets use the canonical example of the User and Address objects::
class User(Base):
__tablename__ = 'user'
-
+
id = Column(Integer, primary_key=True)
name = Column(String(50), nullable=False)
addresses = relationship("Address", backref="user")
-
+
class Address(Base):
__tablename__ = 'address'
id = Column(Integer, primary_key=True)
email_address = Column(String(50), nullable=False)
user_id = Column(Integer, ForeignKey('user.id'), nullable=False)
-
+
Assume a ``User`` object with one ``Address``, already persistent::
>>> u1 = User(name='ed', addresses=[Address(email_address='ed@ed.com')])
>>> session.add(u1)
>>> session.commit()
-
+
We now create ``a1``, an object outside the session, which we'd like
to merge on top of the existing ``Address``::
@@ -450,7 +450,7 @@ to merge on top of the existing ``Address``::
>>> a1 = Address(id=existing_a1.id)
A surprise would occur if we said this::
-
+
>>> a1.user = u1
>>> a1 = session.merge(a1)
>>> session.commit()
@@ -508,7 +508,7 @@ is equivalent to::
>>> existing_a1.id = existing_a1.id
>>> existing_a1.user_id = u1.id
>>> existing_a1.user = None
-
+
Where above, both ``user_id`` and ``user`` are assigned to, and change events
are emitted for both. The ``user`` association
takes precedence, and None is applied to ``user_id``, causing a failure.
@@ -517,11 +517,11 @@ Most :meth:`~.Session.merge` issues can be examined by first checking -
is the object prematurely in the session ?
.. sourcecode:: python+sql
-
+
>>> a1 = Address(id=existing_a1, user_id=user.id)
>>> assert a1 not in session
>>> a1 = session.merge(a1)
-
+
Or is there state on the object that we don't want ? Examining ``__dict__``
is a quick way to check::
@@ -537,7 +537,7 @@ is a quick way to check::
>>> a1 = session.merge(a1)
>>> # success
>>> session.commit()
-
+
Deleting
--------
@@ -900,14 +900,14 @@ place::
>>> session.add(o1)
>>> o1 in session
True
-
+
>>> i1 = Item()
>>> i1.order = o1
>>> i1 in o1.orders
True
>>> i1 in session
True
-
+
This behavior can be disabled as of 0.6.5 using the ``cascade_backrefs`` flag::
mapper(Order, order_table, properties={
@@ -1241,7 +1241,7 @@ entire database interaction is rolled back::
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from unittest import TestCase
-
+
# global application scope. create Session class, engine
Session = sessionmaker()
@@ -1254,23 +1254,23 @@ entire database interaction is rolled back::
# begin a non-ORM transaction
self.trans = connection.begin()
-
+
# bind an individual Session to the connection
self.session = Session(bind=self.connection)
-
+
def test_something(self):
- # use the session in tests.
-
+ # use the session in tests.
+
self.session.add(Foo())
self.session.commit()
-
+
def tearDown(self):
# rollback - everything that happened with the
# Session above (including calls to commit())
# is rolled back.
self.trans.rollback()
self.session.close()
-
+
Above, we issue :meth:`.Session.commit` as well as
:meth:`.Transaction.rollback`. This is an example of where we take advantage
of the :class:`.Connection` object's ability to maintain *subtransactions*, or
@@ -1414,7 +1414,7 @@ Contextual Session API
.. autoclass:: sqlalchemy.util.ScopedRegistry
:members:
-
+
.. autoclass:: sqlalchemy.util.ThreadLocalRegistry
.. _session_partitioning:
@@ -1490,7 +1490,7 @@ those described in :ref:`events_orm_toplevel`.
.. autoclass:: History
:members:
-
+
.. attribute:: sqlalchemy.orm.attributes.PASSIVE_NO_INITIALIZE
Symbol indicating that loader callables should
diff --git a/doc/build/orm/tutorial.rst b/doc/build/orm/tutorial.rst
index b0a4b24c2..2dedf7049 100644
--- a/doc/build/orm/tutorial.rst
+++ b/doc/build/orm/tutorial.rst
@@ -185,10 +185,10 @@ Creating Table, Class and Mapper All at Once Declaratively
The preceding approach to configuration involved a
:class:`~sqlalchemy.schema.Table`, a user-defined class, and
a call to :func:`~.orm.mapper`. This illustrates classical SQLAlchemy usage, which values
-the highest separation of concerns possible.
+the highest separation of concerns possible.
A large number of applications don't require this degree of
separation, and for those SQLAlchemy offers an alternate "shorthand"
-configurational style called :mod:`~.sqlalchemy.ext.declarative`.
+configurational style called :mod:`~.sqlalchemy.ext.declarative`.
For many applications, this is the only style of configuration needed.
Our above example using this style is as follows::
@@ -1440,7 +1440,7 @@ completely and start again.
>>> session.close() # roll back and close the transaction
>>> from sqlalchemy.orm import clear_mappers
>>> clear_mappers() # remove all class mappings
-
+
Below, we use :class:`~.orm.mapper` to reconfigure an ORM mapping for ``User`` and
``Address``, on our existing but currently un-mapped classes. The
diff --git a/doc/build/static/docs.css b/doc/build/static/docs.css
index 23513dbba..697837e94 100644
--- a/doc/build/static/docs.css
+++ b/doc/build/static/docs.css
@@ -86,7 +86,7 @@ h1 {
font: normal 20px/22px arial,helvetica,sans-serif;
color: #222;
padding:0px;
- margin:0px;
+ margin:0px;
}
.topnav h2 {
@@ -94,7 +94,7 @@ h1 {
font-family:arial,helvetica,sans-serif;
font-size:1.6em;
font-weight:normal;
- line-height:1.6em;
+ line-height:1.6em;
}
.topnav h3 {
@@ -185,7 +185,7 @@ div.admonition .admonition-title {
}
.totoc {
-
+
}
.doc_copyright {
diff --git a/doc/build/templates/genindex.mako b/doc/build/templates/genindex.mako
index bdb699a66..b8f776dd2 100644
--- a/doc/build/templates/genindex.mako
+++ b/doc/build/templates/genindex.mako
@@ -30,7 +30,7 @@
% else:
${entryname|h}
% endif
-
+
% if subitems:
<dd><dl>
% for subentryname, subentrylinks in subitems:
diff --git a/doc/build/templates/layout.mako b/doc/build/templates/layout.mako
index d842fdd63..879818efa 100644
--- a/doc/build/templates/layout.mako
+++ b/doc/build/templates/layout.mako
@@ -58,12 +58,12 @@
<div class="topnav">
<div id="pagecontrol">
<a href="${pathto('genindex')}">Index</a>
-
+
% if sourcename:
<div class="sourcelink">(<a href="${pathto('_sources/' + sourcename, True)|h}">${_('view source')})</div>
% endif
</div>
-
+
<div class="navbanner">
<a class="totoc" href="${pathto(master_doc)}">Table of Contents</a>
% if parents:
@@ -74,7 +74,7 @@
% if current_page_name != master_doc:
ยป ${self.show_title()}
% endif
-
+
${prevnext()}
<h2>
${self.show_title()}
@@ -85,7 +85,7 @@
% endif
<div class="clearboth"></div>
</div>
-
+
<div class="document">
<div class="body">
${next.body()}