diff options
-rw-r--r-- | CHANGES | 6 | ||||
-rw-r--r-- | doc/build/content/session.txt | 7 | ||||
-rw-r--r-- | lib/sqlalchemy/databases/postgres.py | 4 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/scoping.py | 2 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/session.py | 27 | ||||
-rw-r--r-- | test/orm/dynamic.py | 4 |
6 files changed, 35 insertions, 15 deletions
@@ -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) |