.. autoclass:: sqlalchemy.engine.url.URL
:members:
+.. _custom_dbapi_args:
+
Custom DBAPI connect() arguments
=================================
.. module:: sqlalchemy.pool
-The establishment of a
-database connection is typically a somewhat expensive operation, and
-applications need a way to get at database connections repeatedly
-with minimal overhead. Particularly for
+A connection pool is a standard technique used to maintain
+long running connections in memory for efficient re-use,
+as well as to provide
+management for the total number of connections an application
+might use simultaneously.
+
+Particularly for
server-side web applications, a connection pool is the standard way to
maintain a "pool" of active database connections in memory which are
reused across requests.
Connection Pool Configuration
-----------------------------
-The :class:`~sqlalchemy.engine.Engine` returned by the
+The :class:`~.engine.base.Engine` returned by the
:func:`~sqlalchemy.create_engine` function in most cases has a :class:`.QueuePool`
integrated, pre-configured with reasonable pooling defaults. If
-you're reading this section to simply enable pooling- congratulations!
+you're reading this section only to learn how to enable pooling - congratulations!
You're already done.
The most common :class:`.QueuePool` tuning parameters can be passed
engine = create_engine('postgresql+psycopg2://', creator=getconn)
For most "initialize on connection" routines, it's more convenient
-to use a :class:`.PoolListener`, so that the usual URL argument to
+to use the :class:`.PoolEvents` event hooks, so that the usual URL argument to
:func:`.create_engine` is still usable. ``creator`` is there as
-a total last resort for when a DBAPI has some form of ``connect``
+a last resort for when a DBAPI has some form of ``connect``
that is not at all supported by SQLAlchemy.
Constructing a Pool
e = create_engine('postgresql://', pool=mypool)
-Pool Event Listeners
---------------------
+Pool Events
+-----------
Connection pools support an event interface that allows hooks to execute
upon first connect, upon each new connection, and upon checkout and
-checkin of connections. See :class:`.PoolListener` for details.
+checkin of connections. See :class:`.PoolEvents` for details.
Dealing with Disconnects
------------------------
raise exc.DisconnectionError()
cursor.close()
-Above, the :class:`.Pool` object specifically catches :class:`.DisconnectionError` and attempts
-to create a new DBAPI connection, up to three times before giving up. This recipe will ensure
+Above, the :class:`.Pool` object specifically catches :class:`~sqlalchemy.exc.DisconnectionError` and attempts
+to create a new DBAPI connection, up to three times, before giving up and then raising
+:class:`~sqlalchemy.exc.InvalidRequestError`, failing the connection. This recipe will ensure
that a new :class:`.Connection` will succeed even if connections
in the pool have gone stale, provided that the database server is actually running. The expense
is that of an additional execution performed per checkout. When using the ORM :class:`.Session`,
A :class:`~sqlalchemy.schema.Table` object can be instructed to load
information about itself from the corresponding database schema object already
-existing within the database. This process is called *reflection*. Most simply
-you need only specify the table name, a :class:`~sqlalchemy.schema.MetaData`
+existing within the database. This process is called *reflection*. In the
+most simple case you need only specify the table name, a :class:`~sqlalchemy.schema.MetaData`
object, and the ``autoload=True`` flag. If the
:class:`~sqlalchemy.schema.MetaData` is not persistently bound, also add the
``autoload_with`` argument::
~~~~~~~~~~~~~~~~~~~~~
A few key :class:`.TypeDecorator` recipes follow.
+.. _coerce_to_unicode:
+
Coercing Encoded Strings to Unicode
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. currentmodule:: sqlalchemy.orm
+=======================================
Collection Configuration and Techniques
=======================================
.. currentmodule:: sqlalchemy.orm
Working with Large Collections
--------------------------------
+===============================
The default behavior of :func:`.relationship` is to fully load
the collection of items in, as according to the loading strategy of the
-relationship. Additionally, the Session by default only knows how to delete
+relationship. Additionally, the :class:`.Session` by default only knows how to delete
objects which are actually present within the session. When a parent instance
-is marked for deletion and flushed, the Session loads its full list of child
+is marked for deletion and flushed, the :class:`.Session` loads its full list of child
items in so that they may either be deleted as well, or have their foreign key
value set to null; this is to avoid constraint violations. For large
collections of child items, there are several strategies to bypass full
loading of child items both at load time as well as deletion time.
+.. _dynamic_relationship:
+
Dynamic Relationship Loaders
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-----------------------------
A key feature to enable management of a large collection is the so-called "dynamic"
relationship. This is an optional form of :func:`~sqlalchemy.orm.relationship` which
returns a :class:`~sqlalchemy.orm.query.Query` object in place of a collection
when accessed. :func:`~sqlalchemy.orm.query.Query.filter` criterion may be
-applied as well as limits and offsets, either explicitly or via array slices:
+applied as well as limits and offsets, either explicitly or via array slices::
-.. sourcecode:: python+sql
+ class User(Base):
+ __tablename__ = 'user'
- mapper(User, users_table, properties={
- 'posts': relationship(Post, lazy="dynamic")
- })
+ posts = relationship(Post, lazy="dynamic")
jack = session.query(User).get(id)
query.
To place a dynamic relationship on a backref, use the :func:`~.orm.backref`
-function in conjunction with ``lazy='dynamic'``:
+function in conjunction with ``lazy='dynamic'``::
-.. sourcecode:: python+sql
+ class Post(Base):
+ __table__ = posts_table
- mapper(Post, posts_table, properties={
- 'user': relationship(User, backref=backref('posts', lazy='dynamic'))
- })
+ user = relationship(User,
+ backref=backref('posts', lazy='dynamic')
+ )
Note that eager/lazy loading options cannot be used in conjunction dynamic relationships at this time.
Setting Noload
-~~~~~~~~~~~~~~~
+---------------
-The opposite of the dynamic relationship is simply "noload", specified using ``lazy='noload'``:
+A "noload" relationship never loads from the database, even when
+accessed. It is configured using ``lazy='noload'``::
-.. sourcecode:: python+sql
+ class MyClass(Base):
+ __tablename__ = 'some_table'
- mapper(MyClass, table, properties={
- 'children': relationship(MyOtherClass, lazy='noload')
- })
+ children = relationship(MyOtherClass, lazy='noload')
Above, the ``children`` collection is fully writeable, and changes to it will
be persisted to the database as well as locally available for reading at the
.. _passive_deletes:
Using Passive Deletes
-~~~~~~~~~~~~~~~~~~~~~~
+----------------------
Use ``passive_deletes=True`` to disable child object loading on a DELETE
operation, in conjunction with "ON DELETE (CASCADE|SET NULL)" on your database
to automatically cascade deletes to child objects. Note that "ON DELETE" is
-not supported on SQLite, and requires ``InnoDB`` tables when using MySQL:
-
-.. sourcecode:: python+sql
-
- mytable = Table('mytable', meta,
- Column('id', Integer, primary_key=True),
- )
+not supported on SQLite, and requires ``InnoDB`` tables when using MySQL::
- myothertable = Table('myothertable', meta,
- Column('id', Integer, primary_key=True),
- Column('parent_id', Integer),
- ForeignKeyConstraint(['parent_id'], ['mytable.id'], ondelete="CASCADE"),
- )
-
- mapper(MyOtherClass, myothertable)
+ class MyClass(Base):
+ __tablename__ = 'mytable'
+ id = Column(Integer, primary_key=True)
+ children = relationship("MyOtherClass",
+ cascade="all, delete-orphan",
+ passive_deletes=True)
- mapper(MyClass, mytable, properties={
- 'children': relationship(MyOtherClass, cascade="all, delete-orphan", passive_deletes=True)
- })
+ class MyOtherClass(Base):
+ __tablename__ = 'myothertable'
+ id = Column(Integer, primary_key=True)
+ parent_id = Column(Integer,
+ ForeignKey('mytable.id', ondelete='CASCADE')
+ )
When ``passive_deletes`` is applied, the ``children`` relationship will not be
loaded into memory when an instance of ``MyClass`` is marked for deletion. The
``MyOtherClass`` which are currently present in the session; however for
instances of ``MyOtherClass`` which are not loaded, SQLAlchemy assumes that
"ON DELETE CASCADE" rules will ensure that those rows are deleted by the
-database and that no foreign key violation will occur.
+database.
.. currentmodule:: sqlalchemy.orm.collections
.. _custom_collections:
Customizing Collection Access
------------------------------
+=============================
Mapping a one-to-many or many-to-many relationship results in a collection of
values accessible through an attribute on the parent instance. By default,
this collection is a ``list``::
- mapper(Parent, properties={
- 'children' : relationship(Child)
- })
+ class Parent(Base):
+ __tablename__ = 'parent'
+ parent_id = Column(Integer, primary_key=True)
+
+ children = relationship(Child)
parent = Parent()
parent.children.append(Child())
Collections are not limited to lists. Sets, mutable sequences and almost any
other Python object that can act as a container can be used in place of the
default list, by specifying the ``collection_class`` option on
-:func:`~sqlalchemy.orm.relationship`.
+:func:`~sqlalchemy.orm.relationship`::
-.. sourcecode:: python+sql
+ class Parent(Base):
+ __tablename__ = 'parent'
+ parent_id = Column(Integer, primary_key=True)
- # use a set
- mapper(Parent, properties={
- 'children' : relationship(Child, collection_class=set)
- })
+ # use a set
+ children = relationship(Child, collection_class=set)
parent = Parent()
child = Child()
assert child in parent.children
Dictionary Collections
-~~~~~~~~~~~~~~~~~~~~~~~
+-----------------------
A little extra detail is needed when using a dictionary as a collection.
This because objects are always loaded from the database as lists, and a key-generation
strategy must be available to populate the dictionary correctly. The
-:func:`.orm.collections.attribute_mapped_collection` function is by far the most common way
+:func:`.attribute_mapped_collection` function is by far the most common way
to achieve a simple dictionary collection. It produces a dictionary class that will apply a particular attribute
of the mapped class as a key. Below we map an ``Item`` class containing
a dictionary of ``Note`` items keyed to the ``Note.keyword`` attribute::
>>> item.notes.items()
{'a': <__main__.Note object at 0x2eaaf0>}
-:func:`.orm.collections.attribute_mapped_collection` will ensure that
+:func:`.attribute_mapped_collection` will ensure that
the ``.keyword`` attribute of each ``Note`` complies with the key in the
dictionary. Such as, when assigning to ``Item.notes``, the dictionary
key we supply must match that of the actual ``Note`` object::
'b': Note('b', 'btext')
}
-The attribute which :func:`.orm.collections.attribute_mapped_collection` uses as a key
-does not need to be mapped at all ! Using a regular Python ``@property`` allows virtually
+The attribute which :func:`.attribute_mapped_collection` uses as a key
+does not need to be mapped at all! Using a regular Python ``@property`` allows virtually
any detail or combination of details about the object to be used as the key, as
below when we establish it as a tuple of ``Note.keyword`` and the first ten letters
of the ``Note.text`` field::
>>> item.notes
{('a', 'atext'): <__main__.Note object at 0x2eaaf0>}
-Other built-in dictionary types include :func:`.orm.collections.column_mapped_collection`,
-which is almost like ``attribute_mapped_collection`` except given the :class:`.Column`
+Other built-in dictionary types include :func:`.column_mapped_collection`,
+which is almost like :func:`.attribute_mapped_collection` except given the :class:`.Column`
object directly::
from sqlalchemy.orm.collections import column_mapped_collection
collection_class=column_mapped_collection(Note.__table__.c.keyword),
cascade="all, delete-orphan")
-as well as :func:`.orm.collections.mapped_collection` which is passed any callable function.
-Note that it's usually easier to use :func:`.orm.collections.attribute_mapped_collection` along
+as well as :func:`.mapped_collection` which is passed any callable function.
+Note that it's usually easier to use :func:`.attribute_mapped_collection` along
with a ``@property`` as mentioned earlier::
from sqlalchemy.orm.collections import mapped_collection
streamlined dictionary views. See :ref:`proxying_dictionaries` and :ref:`composite_association_proxy`
for examples.
+.. autofunction:: attribute_mapped_collection
+
+.. autofunction:: column_mapped_collection
+
+.. autofunction:: mapped_collection
Custom Collection Implementations
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+==================================
-You can use your own types for collections as well. In simple cases, simply
+You can use your own types for collections as well. In simple cases,
inherting from ``list`` or ``set``, adding custom behavior, is all that's needed.
In other cases, special decorators are needed to tell SQLAlchemy more detail
about how the collection operates.
-.. topic:: Do I need a custom collection implementation ?
+.. topic:: Do I need a custom collection implementation?
- In most cases not at all ! The most common use cases for a "custom" collection
+ In most cases not at all! The most common use cases for a "custom" collection
is one that validates or marshals incoming values into a new form, such as
a string that becomes a class instance, or one which goes a
step beyond and represents the data internally in some fashion, presenting
place. Examples of a secondary operation include saving the child item in the
parent's :class:`~sqlalchemy.orm.session.Session` (i.e. the ``save-update``
cascade), as well as synchronizing the state of a bi-directional relationship
-(i.e. a ``backref``).
+(i.e. a :func:`.backref`).
The collections package understands the basic interface of lists, sets and
dicts and will automatically apply instrumentation to those built-in types and
decorator.
Annotating Custom Collections via Decorators
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+--------------------------------------------
Decorators can be used to tag the individual methods the ORM needs to manage
collections. Use them when your class doesn't quite meet the regular interface
-for its container type, or you simply would like to use a different method to
+for its container type, or when you otherwise would like to use a different method to
get the job done.
.. sourcecode:: python+sql
called with a mapped entity as the single argument, and iterator methods are
called with no arguments and must return an iterator.
+.. autoclass:: collection
+ :members:
+
.. _dictionary_collections:
Custom Dictionary-Based Collections
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+-----------------------------------
-The :class:`sqlalchemy.orm.collections.MappedCollection` class can be used as
+The :class:`.MappedCollection` class can be used as
a base class for your custom types or as a mix-in to quickly add ``dict``
collection support to other classes. It uses a keying function to delegate to
``__setitem__`` and ``__delitem__``:
methods in the basic dictionary interface for SQLAlchemy to use by default.
Iteration will go through ``itervalues()`` unless otherwise decorated.
+.. autoclass:: sqlalchemy.orm.collections.MappedCollection
+ :members:
+
Instrumentation and Custom Types
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+--------------------------------
Many custom types and existing library classes can be used as a entity
collection type as-is without further ado. However, it is important to note
-that the instrumentation process _will_ modify the type, adding decorators
+that the instrumentation process will modify the type, adding decorators
around methods automatically.
The decorations are lightweight and no-op outside of relationships, but they
The ORM uses this approach for built-ins, quietly substituting a trivial
subclass when a ``list``, ``set`` or ``dict`` is used directly.
-The collections package provides additional decorators and support for
-authoring custom types. See the :mod:`sqlalchemy.orm.collections` package for
-more information and discussion of advanced usage and Python 2.3-compatible
-decoration options.
+Collection Internals
+=====================
-Collections API
-~~~~~~~~~~~~~~~
+Various internal methods.
-.. autofunction:: attribute_mapped_collection
-
-.. autoclass:: collection
- :members:
+.. autofunction:: bulk_replace
.. autofunction:: collection_adapter
-.. autofunction:: column_mapped_collection
+.. autoclass:: CollectionAdapter
-.. autofunction:: mapped_collection
+.. autoclass:: InstrumentedDict
-.. autoclass:: sqlalchemy.orm.collections.MappedCollection
- :members:
+.. autoclass:: InstrumentedList
+.. autoclass:: InstrumentedSet
+.. autofunction:: prepare_instrumentation
session.query(A).options(joinedload('atob'), joinedload('atob.btoc')).all()
-or more simply just use :func:`~sqlalchemy.orm.joinedload_all` or
+or more succinctly just use :func:`~sqlalchemy.orm.joinedload_all` or
:func:`~sqlalchemy.orm.subqueryload_all`:
.. sourcecode:: python+sql
drizzle+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>
-Character Sets
---------------
+Unicode
+-------
-Drizzle is all utf8 all the time.
+Drizzle accommodates Python ``unicode`` objects directly and
+uses the ``utf8`` encoding in all cases.
Known Issues
-------------
mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>
-Character Sets
---------------
+Unicode
+-------
-Many MySQL server installations default to a ``latin1`` encoding for client
-connections. All data sent through the connection will be converted into
-``latin1``, even if you have ``utf8`` or another character set on your tables
+MySQLdb will accommodate Python ``unicode`` objects if the
+``use_unicode=1`` parameter, or the ``charset`` parameter,
+is passed as a connection argument.
+
+Without this setting, many MySQL server installations default to
+a ``latin1`` encoding for client connections, which has the effect
+of all data being converted into ``latin1``, even if you have ``utf8``
+or another character set configured on your tables
and columns. With versions 4.1 and higher, you can change the connection
character set either through server configuration or by including the
-``charset`` parameter in the URL used for ``create_engine``. The ``charset``
-option is passed through to MySQL-Python and has the side-effect of also
-enabling ``use_unicode`` in the driver by default. For regular encoded
-strings, also pass ``use_unicode=0`` in the connection arguments::
+``charset`` parameter. The ``charset``
+parameter as received by MySQL-Python also has the side-effect of
+enabling ``use_unicode=1``::
+
+ # set client encoding to utf8; all strings come back as unicode
+ create_engine('mysql+mysqldb:///mydb?charset=utf8')
- # set client encoding to utf8; all strings come back as unicode
- create_engine('mysql+mysqldb:///mydb?charset=utf8')
+Manually configuring ``use_unicode=0`` will cause MySQL-python to
+return encoded strings::
- # set client encoding to utf8; all strings come back as utf8 str
- create_engine('mysql+mysqldb:///mydb?charset=utf8&use_unicode=0')
+ # set client encoding to utf8; all strings come back as utf8 str
+ create_engine('mysql+mysqldb:///mydb?charset=utf8&use_unicode=0')
Known Issues
-------------
MySQL-python version 1.2.2 has a serious memory leak related
to unicode conversion, a feature which is disabled via ``use_unicode=0``.
-Using a more recent version of MySQL-python is recommended. The
-recommended connection form with SQLAlchemy is::
-
- engine = create_engine('mysql://scott:tiger@localhost/test?charset=utf8&use_unicode=0', pool_recycle=3600)
-
+It is strongly advised to use the latest version of MySQL-Python.
"""
mysql+oursql://<user>:<password>@<host>[:<port>]/<dbname>
-Character Sets
---------------
+Unicode
+-------
oursql defaults to using ``utf8`` as the connection charset, but other
encodings may be used instead. Like the MySQL-Python driver, unicode support
cx_oracle 5 fully supports Python unicode objects. SQLAlchemy will pass
all unicode strings directly to cx_oracle, and additionally uses an output
handler so that all string based result values are returned as unicode as well.
+Generally, the ``NLS_LANG`` environment variable determines the nature
+of the encoding to be used.
Note that this behavior is disabled when Oracle 8 is detected, as it has been
observed that issues remain when passing Python unicodes to cx_oracle with Oracle 8.
Unicode
-------
-In contrast to SQLAlchemy's active handling of date and time types for pysqlite, pysqlite's
-default behavior regarding Unicode is that all strings are returned as Python unicode objects
-in all cases. So even if the :class:`~sqlalchemy.types.Unicode` type is
-*not* used, you will still always receive unicode data back from a result set. It is
-**strongly** recommended that you do use the :class:`~sqlalchemy.types.Unicode` type
-to represent strings, since it will raise a warning if a non-unicode Python string is
-passed from the user application. Mixing the usage of non-unicode objects with returned unicode objects can
-quickly create confusion, particularly when using the ORM as internal data is not
-always represented by an actual database result string.
+The pysqlite driver only returns Python ``unicode`` objects in result sets, never
+plain strings, and accommodates ``unicode`` objects within bound parameter
+values in all cases. Regardless of the SQLAlchemy string type in use,
+string-based result values will by Python ``unicode`` in Python 2.
+The :class:`.Unicode` type should still be used to indicate those columns that
+require unicode, however, so that non-``unicode`` values passed inadvertently
+will emit a warning. Pysqlite will emit an error if a non-``unicode`` string
+is passed containing non-ASCII characters.
"""
:ref:`connections_toplevel`
- :param assert_unicode: Deprecated. A warning is raised in all cases when a non-Unicode
- object is passed when SQLAlchemy would coerce into an encoding
- (note: but **not** when the DBAPI handles unicode objects natively).
- To suppress or raise this warning to an
- error, use the Python warnings filter documented at:
- http://docs.python.org/library/warnings.html
+ :param assert_unicode: Deprecated. This flag
+ sets an engine-wide default value for
+ the ``assert_unicode`` flag on the
+ :class:`.String` type - see that
+ type for further details.
:param connect_args: a dictionary of options which will be
passed directly to the DBAPI's ``connect()`` method as
- additional keyword arguments.
-
- :param convert_unicode=False: if set to True, all
- String/character based types will convert Python Unicode values to raw
- byte values sent to the DBAPI as bind parameters, and all raw byte values to
- Python Unicode coming out in result sets. This is an
- engine-wide method to provide Unicode conversion across the
- board for those DBAPIs that do not accept Python Unicode objects
- as input. For Unicode conversion on a column-by-column level, use
- the ``Unicode`` column type instead, described in :ref:`types_toplevel`. Note that
- many DBAPIs have the ability to return Python Unicode objects in
- result sets directly - SQLAlchemy will use these modes of operation
- if possible and will also attempt to detect "Unicode returns"
- behavior by the DBAPI upon first connect by the
- :class:`.Engine`. When this is detected, string values in
- result sets are passed through without further processing.
+ additional keyword arguments. See the example
+ at :ref:`custom_dbapi_args`.
+
+ :param convert_unicode=False: if set to True, sets
+ the default behavior of ``convert_unicode`` on the
+ :class:`.String` type to ``True``, regardless
+ of a setting of ``False`` on an individual
+ :class:`.String` type, thus causing all :class:`.String`
+ -based columns
+ to accommodate Python ``unicode`` objects. This flag
+ is useful as an engine-wide setting when using a
+ DBAPI that does not natively support Python
+ ``unicode`` objects and raises an error when
+ one is received (such as pyodbc with FreeTDS).
+
+ See :class:`.String` for further details on
+ what this flag indicates.
:param creator: a callable which returns a DBAPI connection.
This creation function will be passed to the underlying
:ref:`dbengine_logging` for information on how to configure logging
directly.
- :param encoding='utf-8': the encoding to use for all Unicode
- translations, both by engine-wide unicode conversion as well as
- the ``Unicode`` type object.
+ :param encoding: Defaults to ``utf-8``. This is the string
+ encoding used by SQLAlchemy for string encode/decode
+ operations which occur within SQLAlchemy, **outside of
+ the DBAPI.** Most modern DBAPIs feature some degree of
+ direct support for Python ``unicode`` objects,
+ what you see in Python 2 as a string of the form
+ ``u'some string'``. For those scenarios where the
+ DBAPI is detected as not supporting a Python ``unicode``
+ object, this encoding is used to determine the
+ source/destination encoding. It is **not used**
+ for those cases where the DBAPI handles unicode
+ directly.
+
+ To properly configure a system to accommodate Python
+ ``unicode`` objects, the DBAPI should be
+ configured to handle unicode to the greatest
+ degree as is appropriate - see
+ the notes on unicode pertaining to the specific
+ target database in use at :ref:`dialect_toplevel`.
+
+ Areas where string encoding may need to be accommodated
+ outside of the DBAPI include zero or more of:
+
+ * the values passed to bound parameters, corresponding to
+ the :class:`.Unicode` type or the :class:`.String` type
+ when ``convert_unicode`` is ``True``;
+ * the values returned in result set columns corresponding
+ to the :class:`.Unicode` type or the :class:`.String`
+ type when ``convert_unicode`` is ``True``;
+ * the string SQL statement passed to the DBAPI's
+ ``cursor.execute()`` method;
+ * the string names of the keys in the bound parameter
+ dictionary passed to the DBAPI's ``cursor.execute()``
+ as well as ``cursor.setinputsizes()`` methods;
+ * the string column names retrieved from the DBAPI's
+ ``cursor.description`` attribute.
+
+ When using Python 3, the DBAPI is required to support
+ *all* of the above values as Python ``unicode`` objects,
+ which in Python 3 are just known as ``str``. In Python 2,
+ the DBAPI does not specify unicode behavior at all,
+ so SQLAlchemy must make decisions for each of the above
+ values on a per-DBAPI basis - implementations are
+ completely inconsistent in their behavior.
:param execution_options: Dictionary execution options which will
be applied to all connections. See
The ``_ConnectionFairy`` which manages the connection for the span of
the current checkout.
- If you raise an ``exc.DisconnectionError``, the current
+ If you raise a :class:`~sqlalchemy.exc.DisconnectionError`, the current
connection will be disposed and a fresh connection retrieved.
Processing of all checkout listeners will abort and restart
using the new connection.
"""A disconnect is detected on a raw DB-API connection.
This error is raised and consumed internally by a connection pool. It can
- be raised by a ``PoolListener`` so that the host pool forces a disconnect.
+ be raised by the :meth:`.PoolEvents.checkout` event
+ so that the host pool forces a retry; the exception will be caught
+ three times in a row before the pool gives up and raises
+ :class:`~sqlalchemy.exc.InvalidRequestError` regarding the connection attempt.
"""
* ``dynamic`` - the attribute will return a pre-configured
:class:`~sqlalchemy.orm.query.Query` object for all read
operations, onto which further filtering operations can be
- applied before iterating the results. The dynamic
- collection supports a limited set of mutation operations,
- allowing ``append()`` and ``remove()``. Changes to the
- collection will not be visible until flushed
- to the database, where it is then refetched upon iteration.
+ applied before iterating the results. See
+ the section :ref:`dynamic_relationship` for more details.
* True - a synonym for 'select'
dynamic_loader(SomeClass)
- # vs.
+ # is the same as
relationship(SomeClass, lazy="dynamic")
- A :func:`relationship` that is "dynamic" features the behavior
- that read operations return an active :class:`.Query` object which
- reads from the database when accessed. Items may be appended to the
- attribute via ``append()``, or removed via ``remove()``; changes will be
- persisted to the database during a :meth:`Sesion.flush`. However, no other
- Python list or collection mutation operations are available.
-
- All arguments accepted by :func:`relationship` are
- accepted here, other than ``lazy`` which is fixed at ``dynamic``.
+ See the section :ref:`dynamic_relationship` for more details
+ on dynamic loading.
"""
kw['lazy'] = 'dynamic'
def column_mapped_collection(mapping_spec):
"""A dictionary-based collection type with column-based keying.
- Returns a MappedCollection factory with a keying function generated
+ Returns a :class:`.MappedCollection` factory with a keying function generated
from mapping_spec, which may be a Column or a sequence of Columns.
The key value must be immutable for the lifetime of the object. You
def attribute_mapped_collection(attr_name):
"""A dictionary-based collection type with attribute-based keying.
- Returns a MappedCollection factory with a keying based on the
+ Returns a :class:`.MappedCollection` factory with a keying based on the
'attr_name' attribute of entities in the collection, where ``attr_name``
is the string name of the attribute.
def mapped_collection(keyfunc):
"""A dictionary-based collection type with arbitrary keying.
- Returns a MappedCollection factory with a keying function generated
+ Returns a :class:`.MappedCollection` factory with a keying function generated
from keyfunc, a callable that takes an entity and returns a key value.
The key value must be immutable for the lifetime of the object. You
@collection.removes_return()
def popitem(self): ...
- Decorators can be specified in long-hand for Python 2.3, or with
- the class-level dict attribute '__instrumentation__'- see the source
- for details.
-
"""
# Bundled as a class solely for ease of use: packaging, doc strings,
# importability.
to the underlying Python collection, and emits add/remove events for
entities entering or leaving the collection.
- The ORM uses an CollectionAdapter exclusively for interaction with
+ The ORM uses :class:`.CollectionAdapter` exclusively for interaction with
entity collections.
The usage of getattr()/setattr() is currently to allow injection
instances in ``existing_adapter`` not present in ``values`` will have
remove events fired upon them.
- values
- An iterable of collection member instances
+ :param values: An iterable of collection member instances
- existing_adapter
- A CollectionAdapter of instances to be replaced
+ :param existing_adapter: A :class:`.CollectionAdapter` of instances to be replaced
- new_adapter
- An empty CollectionAdapter to load with ``values``
+ :param new_adapter: An empty :class:`.CollectionAdapter` to load with ``values``
"""
:param length: optional, a length for the column for use in
DDL statements. May be safely omitted if no ``CREATE
TABLE`` will be issued. Certain databases may require a
- *length* for use in DDL, and will raise an exception when
- the ``CREATE TABLE`` DDL is issued. Whether the value is
+ ``length`` for use in DDL, and will raise an exception when
+ the ``CREATE TABLE`` DDL is issued if a ``VARCHAR``
+ with no length is included. Whether the value is
interpreted as bytes or characters is database specific.
- :param convert_unicode: defaults to False. If True, the
- type will do what is necessary in order to accept
- Python Unicode objects as bind parameters, and to return
- Python Unicode objects in result rows. This may
- require SQLAlchemy to explicitly coerce incoming Python
- unicodes into an encoding, and from an encoding
- back to Unicode, or it may not require any interaction
- from SQLAlchemy at all, depending on the DBAPI in use.
-
- When SQLAlchemy performs the encoding/decoding,
- the encoding used is configured via
- :attr:`~sqlalchemy.engine.base.Dialect.encoding`, which
- defaults to `utf-8`.
-
- The "convert_unicode" behavior can also be turned on
- for all String types by setting
- :attr:`sqlalchemy.engine.base.Dialect.convert_unicode`
- on create_engine().
-
- To instruct SQLAlchemy to perform Unicode encoding/decoding
- even on a platform that already handles Unicode natively,
- set convert_unicode='force'. This will incur significant
- performance overhead when fetching unicode result columns.
-
- :param assert_unicode: Deprecated. A warning is raised in all cases
- when a non-Unicode object is passed when SQLAlchemy would coerce
- into an encoding (note: but **not** when the DBAPI handles unicode
- objects natively). To suppress or raise this warning to an error,
- use the Python warnings filter documented at:
- http://docs.python.org/library/warnings.html
+ :param convert_unicode: When set to ``True``, the
+ :class:`.String` type will assume that
+ input is to be passed as Python ``unicode`` objects,
+ and results returned as Python ``unicode`` objects.
+ If the DBAPI in use does not support Python unicode
+ (which is fewer and fewer these days), SQLAlchemy
+ will encode/decode the value, using the
+ value of the ``encoding`` parameter passed to
+ :func:`.create_engine` as the encoding.
+
+ When using a DBAPI that natively supports Python
+ unicode objects, this flag generally does not
+ need to be set. For columns that are explicitly
+ intended to store non-ASCII data, the :class:`.Unicode`
+ or :class:`UnicodeText`
+ types should be used regardless, which feature
+ the same behavior of ``convert_unicode`` but
+ also indicate an underlying column type that
+ directly supports unicode, such as ``NVARCHAR``.
+
+ For the extremely rare case that Python ``unicode``
+ is to be encoded/decoded by SQLAlchemy on a backend
+ that does natively support Python ``unicode``,
+ the value ``force`` can be passed here which will
+ cause SQLAlchemy's encode/decode services to be
+ used unconditionally.
+
+ :param assert_unicode: Deprecated. A warning is emitted
+ when a non-``unicode`` object is passed to the
+ :class:`.Unicode` subtype of :class:`.String`,
+ or the :class:`.UnicodeText` subtype of :class:`.Text`.
+ See :class:`.Unicode` for information on how to
+ control this warning.
:param unicode_error: Optional, a method to use to handle Unicode
- conversion errors. Behaves like the 'errors' keyword argument to
- the standard library's string.decode() functions. This flag
- requires that `convert_unicode` is set to `"force"` - otherwise,
+ conversion errors. Behaves like the ``errors`` keyword argument to
+ the standard library's ``string.decode()`` functions. This flag
+ requires that ``convert_unicode`` is set to ``force`` - otherwise,
SQLAlchemy is not guaranteed to handle the task of unicode
conversion. Note that this flag adds significant performance
overhead to row-fetching operations for backends that already
return unicode objects natively (which most DBAPIs do). This
- flag should only be used as an absolute last resort for reading
- strings from a column with varied or corrupted encodings,
- which only applies to databases that accept invalid encodings
- in the first place (i.e. MySQL. *not* PG, Sqlite, etc.)
+ flag should only be used as a last resort for reading
+ strings from a column with varied or corrupted encodings.
"""
if unicode_error is not None and convert_unicode != 'force':
__visit_name__ = 'text'
class Unicode(String):
- """A variable length Unicode string.
-
- The ``Unicode`` type is a :class:`.String` which converts Python
- ``unicode`` objects (i.e., strings that are defined as
- ``u'somevalue'``) into encoded bytestrings when passing the value
- to the database driver, and similarly decodes values from the
- database back into Python ``unicode`` objects.
-
- It's roughly equivalent to using a ``String`` object with
- ``convert_unicode=True``, however
- the type has other significances in that it implies the usage
- of a unicode-capable type being used on the backend, such as NVARCHAR.
- This may affect what type is emitted when issuing CREATE TABLE
- and also may effect some DBAPI-specific details, such as type
- information passed along to ``setinputsizes()``.
-
- When using the ``Unicode`` type, it is only appropriate to pass
- Python ``unicode`` objects, and not plain ``str``. If a
- bytestring (``str``) is passed, a runtime warning is issued. If
- you notice your application raising these warnings but you're not
- sure where, the Python ``warnings`` filter can be used to turn
- these warnings into exceptions which will illustrate a stack
- trace::
+ """A variable length Unicode string type.
+
+ The :class:`.Unicode` type is a :class:`.String` subclass
+ that assumes input and output as Python ``unicode`` data,
+ and in that regard is equivalent to the usage of the
+ ``convert_unicode`` flag with the :class:`.String` type.
+ However, unlike plain :class:`.String`, it also implies an
+ underlying column type that is explicitly supporting of non-ASCII
+ data, such as ``NVARCHAR`` on Oracle and SQL Server.
+ This can impact the output of ``CREATE TABLE`` statements
+ and ``CAST`` functions at the dialect level, and can
+ also affect the handling of bound parameters in some
+ specific DBAPI scenarios.
+
+ The encoding used by the :class:`.Unicode` type is usually
+ determined by the DBAPI itself; most modern DBAPIs
+ feature support for Python ``unicode`` objects as bound
+ values and result set values, and the encoding should
+ be configured as detailed in the notes for the target
+ DBAPI in the :ref:`dialect_toplevel` section.
+
+ For those DBAPIs which do not support, or are not configured
+ to accommodate Python ``unicode`` objects
+ directly, SQLAlchemy does the encoding and decoding
+ outside of the DBAPI. The encoding in this scenario
+ is determined by the ``encoding`` flag passed to
+ :func:`.create_engine`.
+
+ When using the :class:`.Unicode` type, it is only appropriate
+ to pass Python ``unicode`` objects, and not plain ``str``.
+ If a plain ``str`` is passed under Python 2, a warning
+ is emitted. If you notice your application emitting these warnings but
+ you're not sure of the source of them, the Python
+ ``warnings`` filter, documented at
+ http://docs.python.org/library/warnings.html,
+ can be used to turn these warnings into exceptions
+ which will illustrate a stack trace::
import warnings
warnings.simplefilter('error')
- Bytestrings sent to and received from the database are encoded
- using the dialect's
- :attr:`~sqlalchemy.engine.base.Dialect.encoding`, which defaults
- to `utf-8`.
+ For an application that wishes to pass plain bytestrings
+ and Python ``unicode`` objects to the ``Unicode`` type
+ equally, the bytestrings must first be decoded into
+ unicode. The recipe at :ref:`coerce_to_unicode` illustrates
+ how this is done.
+
+ See also:
+
+ :class:`.UnicodeText` - unlengthed textual counterpart
+ to :class:`.Unicode`.
"""
def __init__(self, length=None, **kwargs):
"""
- Create a Unicode-converting String type.
-
- :param length: optional, a length for the column for use in
- DDL statements. May be safely omitted if no ``CREATE
- TABLE`` will be issued. Certain databases may require a
- *length* for use in DDL, and will raise an exception when
- the ``CREATE TABLE`` DDL is issued. Whether the value is
- interpreted as bytes or characters is database specific.
-
- :param \**kwargs: passed through to the underlying ``String``
- type.
+ Create a :class:`.Unicode` object.
+
+ Parameters are the same as that of :class:`.String`,
+ with the exception that ``convert_unicode``
+ defaults to ``True``.
"""
kwargs.setdefault('convert_unicode', True)
super(Unicode, self).__init__(length=length, **kwargs)
class UnicodeText(Text):
- """An unbounded-length Unicode string.
+ """An unbounded-length Unicode string type.
See :class:`.Unicode` for details on the unicode
behavior of this object.
- Like ``Unicode``, usage the ``UnicodeText`` type implies a
- unicode-capable type being used on the backend, such as NCLOB.
+ Like :class:`.Unicode`, usage the :class:`.UnicodeText` type implies a
+ unicode-capable type being used on the backend, such as
+ ``NCLOB``, ``NTEXT``.
"""
"""
Create a Unicode-converting Text type.
- :param length: optional, a length for the column for use in
- DDL statements. May be safely omitted if no ``CREATE
- TABLE`` will be issued. Certain databases may require a
- *length* for use in DDL, and will raise an exception when
- the ``CREATE TABLE`` DDL is issued. Whether the value is
- interpreted as bytes or characters is database specific.
+ Parameters are the same as that of :class:`.Text`,
+ with the exception that ``convert_unicode``
+ defaults to ``True``.
"""
kwargs.setdefault('convert_unicode', True)