docstring stuff

This commit is contained in:
Mike Bayer
2007-08-05 20:19:26 +00:00
parent 0d7bce40f8
commit 942cba7208
6 changed files with 115 additions and 17 deletions
+2 -4
View File
@@ -38,14 +38,12 @@ def make_all_docs():
make_doc(obj=orm.interfaces),
make_doc(obj=orm.mapperlib, classes=[orm.mapperlib.MapperExtension, orm.mapperlib.Mapper]),
make_doc(obj=orm.properties),
make_doc(obj=orm.query, classes=[orm.query.Query, orm.query.QueryContext, orm.query.SelectionContext]),
make_doc(obj=orm.session, classes=[orm.session.Session, orm.session.SessionTransaction]),
make_doc(obj=orm.query, classes=[orm.query.Query]),
make_doc(obj=orm.session, classes=[orm.session.Session]),
make_doc(obj=orm.shard),
make_doc(obj=exceptions),
make_doc(obj=assignmapper),
make_doc(obj=associationproxy, classes=[associationproxy.AssociationProxy]),
make_doc(obj=orderinglist, classes=[orderinglist.OrderingList]),
make_doc(obj=sessioncontext),
make_doc(obj=sqlsoup),
] + [make_doc(getattr(__import__('sqlalchemy.databases.%s' % m).databases, m)) for m in databases.__all__]
return objects
+34 -3
View File
@@ -21,24 +21,55 @@ from sqlalchemy.orm.query import Query
from sqlalchemy.orm.util import polymorphic_union
from sqlalchemy.orm.session import Session as _Session
from sqlalchemy.orm.session import object_session, attribute_manager, sessionmaker
from sqlalchemy.orm.scoping import ScopedSession as scoped_session
from sqlalchemy.orm.scoping import ScopedSession
__all__ = [ 'relation', 'column_property', 'composite', 'backref', 'eagerload',
'eagerload_all', 'lazyload', 'noload', 'deferred', 'defer',
'undefer', 'undefer_group', 'extension', 'mapper', 'clear_mappers',
'compile_mappers', 'class_mapper', 'object_mapper', 'sessionmaker',
'scoped_session', 'dynamic_loader', 'MapperExtension', 'Query', 'polymorphic_union',
'scoped_session', 'dynamic_loader', 'MapperExtension', 'polymorphic_union',
'create_session', 'synonym', 'contains_alias',
'contains_eager', 'EXT_CONTINUE', 'EXT_STOP', 'EXT_PASS',
'object_session', 'PropComparator' ]
def scoped_session(session_factory, scopefunc=None):
"""Provides thread-local management of Sessions.
Usage::
Session = scoped_session(sessionmaker(autoflush=True))
To instantiate a Session object which is part of the scoped
context, instantiate normally::
session = Session()
Most session methods are available as classmethods from
the scoped session::
Session.commit()
Session.close()
To map classes so that new instances are saved in the current
Session automatically, as well as to provide session-aware
class attributes such as "query", use the `mapper` classmethod
from the scoped session::
mapper = Session.mapper
mapper(Class, table, ...)
"""
return ScopedSession(session_factory, scopefunc=scopefunc)
def create_session(bind=None, **kwargs):
"""create a new [sqlalchemy.orm.session#Session].
The session by default does not begin a transaction, and requires that
flush() be called explicitly in order to persist results to the database.
It is recommended to use the sessionmaker() function instead of create_session().
It is recommended to use the [sqlalchemy.orm#sessionmaker()] function
instead of create_session().
"""
kwargs.setdefault('autoflush', False)
kwargs.setdefault('transactional', False)
+2 -1
View File
@@ -2,7 +2,8 @@
a special AttributeHistory on the 'write' side."""
from sqlalchemy import exceptions
from sqlalchemy.orm import attributes, Query, object_session
from sqlalchemy.orm import attributes, object_session
from sqlalchemy.orm.query import Query
from sqlalchemy.orm.mapper import has_identity
class DynamicCollectionAttribute(attributes.InstrumentedAttribute):
+72 -4
View File
@@ -159,11 +159,79 @@ class SessionTransaction(object):
self.rollback()
class Session(object):
"""Encapsulates a set of objects being operated upon within an
object-relational operation.
"""Encapsulates a set of objects being operated upon within an object-relational operation.
The Session object is **not** threadsafe. For thread-management
of Sessions, see the ``sqlalchemy.ext.sessioncontext`` module.
The Session is the front end to SQLAlchemy's **Unit of Work** implementation. The concept
behind Unit of Work is to track modifications to a field of objects, and then be able to
flush those changes to the database in a single operation.
SQLAlchemy's unit of work includes these functions:
* The ability to track in-memory changes on scalar- and collection-based object
attributes, such that database persistence operations can be assembled based on those
changes.
* The ability to organize individual SQL queries and population of newly generated
primary and foreign key-holding attributes during a persist operation
such that referential integrity is maintained at all times.
* The ability to maintain insert ordering against the order in which
new instances were added to the session.
* an Identity Map, which is a dictionary keying instances to their unique primary key
identity. This ensures that only one copy of a particular entity is ever present
within the session, even if repeated load operations for the same entity occur. This
allows many parts of an application to get a handle to a particular object without
any chance of modifications going to two different places.
When dealing with instances of mapped classes, an instance may be *attached* to a
particular Session, else it is *unattached* . An instance also may or may not correspond
to an actual row in the database. These conditions break up into four distinct states:
* *Transient* - a transient instance exists within memory only and is not associated with
any Session. It also has no database identity and does not have a corresponding record
in the database. When a new instance of a class is constructed, and no default session
context exists with which to automatically attach the new instance, it is a transient
instance. The instance can then be saved to a particular session in which case it
becomes a *pending* instance. If a default session context exists, new instances are
added to that Session by default and therefore become *pending* instances immediately.
* *Pending* - a pending instance is a Session-attached object that has not yet been
assigned a database identity. When the Session is flushed (i.e. changes are persisted to
the database), a pending instance becomes persistent.
* *Persistent* - a persistent instance has a database identity and a corresponding record
in the database, and is also associated with a particular Session. By "database
identity" we mean the object is associated with a table or relational concept in the
database combined with a particular primary key in that table. Objects that are loaded
by SQLAlchemy in the context of a particular session are automatically considered
persistent, as are formerly pending instances which have been subject to a session
`flush()`.
* *Detached* - a detached instance is an instance which has a database identity and
corresponding row in the database, but is not attached to any Session. This occurs when
an instance has been removed from a Session, either because the session itself was
cleared or closed, or the instance was explicitly removed from the Session. The object
can be re-attached to a session in which case it becomes Persistent again; any
un-persisted changes that exist on the instance, whether they occurred during its
previous persistent state or during its detached state will be detected and maintained
by the new session. Detached instances are useful when an application needs to represent
a long-running operation across multiple Sessions, needs to store an object in a
serialized state and then restore it later (such as within an HTTP "session" object), or
in some cases where code needs to load instances locally which will later be associated
with some other Session.
The session methods which control instance state include ``save()``, ``update()``,
``save_or_update()``, ``delete()``, ``merge()``, and ``expunge()``.
The Session object is **not** threadsafe, particularly during flush operations. A session
which is only read from (i.e. is never flushed) can be used by concurrent threads if it's
acceptable that some object instances may be loaded twice.
The typical pattern to managing Sessions in a multi-threaded environment is either to use
mutexes to limit concurrent access to one thread at a time, or more commonly to establish
a unique session for every thread, using a threadlocal variable. SQLAlchemy provides
a thread-managed Session adapter, provided by the [sqlalchemy.orm#scoped_session()] function.
"""
def __init__(self, bind=None, autoflush=True, transactional=False, twophase=False, echo_uow=False, weak_identity_map=False):
+1 -1
View File
@@ -1,5 +1,5 @@
from sqlalchemy.orm.session import Session
from sqlalchemy.orm import Query
from sqlalchemy.orm.query import Query
__all__ = ['ShardedSession', 'ShardedQuery']
+4 -4
View File
@@ -640,7 +640,7 @@ class DefaultTest(UnitOfWorkTest):
Session.close()
l = Query(Hoho).select()
l = Hoho.query.all()
(h1, h2, h3, h4, h5) = l
@@ -941,7 +941,7 @@ class SaveTest(UnitOfWorkTest):
# select both
#Session.close()
userlist = Query(m).select(users.c.user_id.in_(u.user_id, u2.user_id), order_by=[users.c.user_name])
userlist = User.query.filter(users.c.user_id.in_(u.user_id, u2.user_id)).order_by([users.c.user_name]).all()
print repr(u.user_id), repr(userlist[0].user_id), repr(userlist[0].user_name)
self.assert_(u.user_id == userlist[0].user_id and userlist[0].user_name == 'modifiedname')
self.assert_(u2.user_id == userlist[1].user_id and userlist[1].user_name == 'savetester2')
@@ -1464,7 +1464,7 @@ class ManyToManyTest(UnitOfWorkTest):
item.keywords = []
for kname in [e['keyword'][1]['name'] for e in elem['keywords'][1]]:
try:
k = Query(keywordmapper).select(keywords.c.name == kname)[0]
k = Keyword.query.filter(keywords.c.name == kname)[0]
except IndexError:
k = Keyword()
k.name= kname
@@ -1474,7 +1474,7 @@ class ManyToManyTest(UnitOfWorkTest):
Session.commit()
Session.close()
l = Query(m).select(items.c.item_name.in_(*[e['item_name'] for e in data[1:]]), order_by=[items.c.item_name])
l = Item.query.filter(items.c.item_name.in_(*[e['item_name'] for e in data[1:]])).order_by(items.c.item_name).all()
self.assert_result(l, *data)
def testm2mmultitable(self):