summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES6
-rw-r--r--doc/build/content/session.txt7
-rw-r--r--lib/sqlalchemy/databases/postgres.py4
-rw-r--r--lib/sqlalchemy/orm/scoping.py2
-rw-r--r--lib/sqlalchemy/orm/session.py27
-rw-r--r--test/orm/dynamic.py4
6 files changed, 35 insertions, 15 deletions
diff --git a/CHANGES b/CHANGES
index 700db631e..d1d55cd44 100644
--- a/CHANGES
+++ b/CHANGES
@@ -302,6 +302,12 @@
- mssql
- added support for TIME columns (simulated using DATETIME) [ticket:679]
- index names are now quoted when dropping from reflected tables [ticket:684]
+- postgres
+ - when reflecting tables from alternate schemas, the "default" placed upon
+ the primary key, i.e. usually a sequence name, has the "schema" name
+ unconditionally quoted, so that schema names which need quoting are fine.
+ its slightly unnecessary for schema names which don't need quoting
+ but not harmful.
0.3.10
- general
diff --git a/doc/build/content/session.txt b/doc/build/content/session.txt
index 7fb998ab9..938815c4c 100644
--- a/doc/build/content/session.txt
+++ b/doc/build/content/session.txt
@@ -1,4 +1,4 @@
-Using the Session {@name=unitofwork}
+ Using the Session {@name=unitofwork}
============
The [Mapper](rel:advdatamapping) is the entrypoint to the configurational API of the SQLAlchemy object relational mapper. But the primary object one works with when using the ORM is the [Session](rel:docstrings_sqlalchemy.orm.session_Session).
@@ -156,9 +156,10 @@ Knowing these states is important, since the `Session` tries to be strict about
* How can I get the `Session` for a certain object ?
+ Use the `object_session()` classmethod available on `Session`:
+
{python}
- from sqlalchemy.orm import object_session
- session = object_session(someobject)
+ session = Session.object_session(someobject)
* Is the session threadsafe ?
diff --git a/lib/sqlalchemy/databases/postgres.py b/lib/sqlalchemy/databases/postgres.py
index d3467105b..8f04eca26 100644
--- a/lib/sqlalchemy/databases/postgres.py
+++ b/lib/sqlalchemy/databases/postgres.py
@@ -447,7 +447,9 @@ class PGDialect(ansisql.ANSIDialect):
# the default is related to a Sequence
sch = table.schema
if '.' not in match.group(2) and sch is not None:
- default = match.group(1) + sch + '.' + match.group(2) + match.group(3)
+ # unconditionally quote the schema name. this could
+ # later be enhanced to obey quoting rules / "quote schema"
+ default = match.group(1) + ('"%s"' % sch) + '.' + match.group(2) + match.group(3)
colargs.append(schema.PassiveDefault(sql.text(default)))
table.append_column(schema.Column(name, coltype, nullable=nullable, *colargs))
diff --git a/lib/sqlalchemy/orm/scoping.py b/lib/sqlalchemy/orm/scoping.py
index fc2fba87b..86050e975 100644
--- a/lib/sqlalchemy/orm/scoping.py
+++ b/lib/sqlalchemy/orm/scoping.py
@@ -81,7 +81,7 @@ def clslevel(name):
def do(cls, *args,**kwargs):
return getattr(Session, name)(*args, **kwargs)
return classmethod(do)
-for prop in ('close_all',):
+for prop in ('close_all','object_session', 'identity_key'):
setattr(ScopedSession, prop, clslevel(prop))
class _ScopedExt(MapperExtension):
diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py
index e7268dd98..ab12d4c14 100644
--- a/lib/sqlalchemy/orm/session.py
+++ b/lib/sqlalchemy/orm/session.py
@@ -502,12 +502,6 @@ class Session(object):
self.uow = unitofwork.UnitOfWork(weak_identity_map=self.weak_identity_map)
self.uow.echo = echo
- def mapper(self, class_, entity_name=None):
- """Given a ``Class``, return the primary ``Mapper`` responsible for
- persisting it."""
-
- return _class_mapper(class_, entity_name = entity_name)
-
def bind_mapper(self, mapper, bind, entity_name=None):
"""Bind the given `mapper` or `class` to the given ``Engine`` or ``Connection``.
@@ -801,7 +795,7 @@ class Session(object):
finally:
_recursive.remove(mapper)
- def identity_key(self, *args, **kwargs):
+ def identity_key(cls, *args, **kwargs):
"""Get an identity key.
Valid call signatures:
@@ -863,7 +857,14 @@ class Session(object):
% ", ".join(kwargs.keys()))
mapper = _object_mapper(instance)
return mapper.identity_key_from_instance(instance)
-
+ identity_key = classmethod(identity_key)
+
+ def object_session(cls, obj):
+ """return the ``Session`` to which the given object belongs."""
+
+ return object_session(obj)
+ object_session = classmethod(object_session)
+
def _save_impl(self, object, **kwargs):
if hasattr(object, '_instance_key'):
if not self.identity_map.has_key(object._instance_key):
@@ -942,15 +943,25 @@ class Session(object):
return getattr(obj, '_sa_session_id', None) == self.hash_key
def __contains__(self, obj):
+ """return True if the given object is associated with this session.
+
+ The instance may be pending or persistent within the Session for a
+ result of True.
+ """
+
return self._is_attached(obj) and (obj in self.uow.new or self.identity_map.has_key(obj._instance_key))
def __iter__(self):
+ """return an iterator of all objects which are pending or persistent within this Session."""
+
return iter(list(self.uow.new) + self.uow.identity_map.values())
def _get(self, key):
return self.identity_map[key]
def has_key(self, key):
+ """return True if the given identity key is present within this Session's identity map."""
+
return self.identity_map.has_key(key)
dirty = property(lambda s:s.uow.locate_dirty(),
diff --git a/test/orm/dynamic.py b/test/orm/dynamic.py
index ac6764653..3cca2f7f1 100644
--- a/test/orm/dynamic.py
+++ b/test/orm/dynamic.py
@@ -144,8 +144,8 @@ def create_backref_test(autoflush, saveuser):
sess.flush()
self.assert_(list(u.addresses) == [])
- test_backref.__name__ = "test_%s%s" % (
- (autoflush and "autoflush" or ""),
+ test_backref.__name__ = "test%s%s" % (
+ (autoflush and "_autoflush" or ""),
(saveuser and "_saveuser" or "_savead"),
)
setattr(FlushTest, test_backref.__name__, test_backref)