From e1ceee15cd7e5692513ac83716b3201a47a0272e Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sat, 6 Jan 2007 03:33:53 +0000 Subject: [PATCH] - added an error message if you actually try to modify primary key values on an entity and then flush it. --- CHANGES | 2 ++ lib/sqlalchemy/orm/mapper.py | 5 ++++- test/orm/unitofwork.py | 19 +++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 798d33fac0..423a47e7c8 100644 --- a/CHANGES +++ b/CHANGES @@ -24,6 +24,8 @@ required for firebird, not a bad idea for others [ticket:408] - default "timezone" setting is now False. this corresponds to Python's datetime behavior as well as Postgres' timestamp/time types (which is the only timezone-sensitive dialect at the moment) [ticket:414] +- added an error message if you actually try to modify primary key values on an entity +and then flush it. 0.3.3 - string-based FROM clauses fixed, i.e. select(..., from_obj=["sometext"]) diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index 67ca75bb3d..b6ff096169 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -841,7 +841,10 @@ class Mapper(object): if self.__should_log_debug: self.__log_debug("detected row switch for identity %s. will update %s, remove %s from transaction" % (instance_key, mapperutil.instance_str(obj), mapperutil.instance_str(existing))) uowtransaction.unregister_object(existing) - + if has_identity(obj): + if obj._instance_key != instance_key: + raise exceptions.FlushError("Can't change the identity of instance %s in session (existing identity: %s; new identity: %s)" % (mapperutil.instance_str(obj), obj._instance_key, instance_key)) + inserted_objects = util.Set() updated_objects = util.Set() diff --git a/test/orm/unitofwork.py b/test/orm/unitofwork.py index ed3b9fca1d..c1f885bb0e 100644 --- a/test/orm/unitofwork.py +++ b/test/orm/unitofwork.py @@ -3,6 +3,7 @@ from sqlalchemy import * import testbase import pickleable from sqlalchemy.orm.mapper import global_extensions +from sqlalchemy.orm import util as ormutil from sqlalchemy.ext.sessioncontext import SessionContext import sqlalchemy.ext.assignmapper as assignmapper from tables import * @@ -403,6 +404,24 @@ class PKTest(UnitOfWorkTest): e.data = 'some more data' ctx.current.flush() + def testpksimmutable(self): + class Entry(object): + pass + mapper(Entry, table) + e = Entry() + e.multi_id=5 + e.multi_rev=5 + e.name='somename' + ctx.current.flush() + e.multi_rev=6 + e.name = 'someothername' + try: + ctx.current.flush() + assert False + except exceptions.FlushError, fe: + assert str(fe) == "Can't change the identity of instance Entry@%s in session (existing identity: (%s, (5, 5), None); new identity: (%s, (5, 6), None))" % (hex(id(e)), repr(e.__class__), repr(e.__class__)) + + class ForeignPKTest(UnitOfWorkTest): """tests mapper detection of the relationship direction when parent/child tables are joined on their primary keys""" -- 2.47.2