[Sqlalchemy-tickets] Issue #3006: orm DELETE not using DB-persited PK in the event of PK change (zz
Brought to you by:
zzzeek
|
From: Mike B. <iss...@bi...> - 2014-03-28 19:32:14
|
New issue 3006: orm DELETE not using DB-persited PK in the event of PK change https://bitbucket.org/zzzeek/sqlalchemy/issue/3006/orm-delete-not-using-db-persited-pk-in-the Mike Bayer: ``` #!python from sqlalchemy import * from sqlalchemy.orm import * from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class A(Base): __tablename__ = 'a' id = Column(Integer, primary_key=True) e = create_engine("sqlite://", echo=True) #e = create_engine('postgresql://scott:tiger@localhost/test', echo=True) Base.metadata.drop_all(e) Base.metadata.create_all(e) sess = Session(e) a1 = A(id=1) sess.add(a1) sess.commit() a1.id = 2 sess.delete(a1) sess.commit() ``` note that we will turn on "multi rowcount" checking which seems to have been removed, also psycopg2 supports this now: ``` #!diff diff --git a/lib/sqlalchemy/dialects/postgresql/psycopg2.py b/lib/sqlalchemy/dialects/postgresql/psycopg2.py index 099ddf0..ac17706 100644 --- a/lib/sqlalchemy/dialects/postgresql/psycopg2.py +++ b/lib/sqlalchemy/dialects/postgresql/psycopg2.py @@ -347,7 +347,7 @@ class PGDialect_psycopg2(PGDialect): supports_unicode_statements = False default_paramstyle = 'pyformat' - supports_sane_multi_rowcount = False + supports_sane_multi_rowcount = False # set to true based on psycopg2 version execution_ctx_cls = PGExecutionContext_psycopg2 statement_compiler = PGCompiler_psycopg2 preparer = PGIdentifierPreparer_psycopg2 @@ -393,6 +393,9 @@ class PGDialect_psycopg2(PGDialect): is not None self._has_native_json = self.psycopg2_version >= (2, 5) + # http://initd.org/psycopg/docs/news.html#what-s-new-in-psycopg-2-0-9 + self.supports_sane_multi_rowcount = self.psycopg2_version >= (2, 0, 9) + @classmethod def dbapi(cls): import psycopg2 diff --git a/lib/sqlalchemy/orm/persistence.py b/lib/sqlalchemy/orm/persistence.py index 3563198..7a9f3d5 100644 --- a/lib/sqlalchemy/orm/persistence.py +++ b/lib/sqlalchemy/orm/persistence.py @@ -702,7 +702,16 @@ def _emit_delete_statements(base_mapper, uowtransaction, cached_connections, stacklevel=12) connection.execute(statement, del_objects) else: - connection.execute(statement, del_objects) + c = connection.execute(statement, del_objects) + if connection.dialect.supports_sane_multi_rowcount and \ + c.rowcount != len(del_objects): + raise orm_exc.StaleDataError( + "DELETE statement on table '%s' expected to " + "delete %d row(s); %d were matched." % + (table.description, len(del_objects), c.rowcount) + ) + + def _finalize_insert_update_commands(base_mapper, uowtransaction, ``` |