Mike Bayer avatar Mike Bayer committed 5c3604f

- [bug] When the primary key column of a Table
is replaced, such as via extend_existing,
the "auto increment" column used by insert()
constructs is reset. Previously it would
remain referring to the previous primary
key column. [ticket:2525]

Comments (0)

Files changed (4)

     returned by SQLite cursor.description.
     [ticket:2475]
 
+  - [bug] When the primary key column of a Table
+    is replaced, such as via extend_existing,
+    the "auto increment" column used by insert()
+    constructs is reset.  Previously it would
+    remain referring to the previous primary
+    key column.  [ticket:2525]
 
 0.7.6
 =====

lib/sqlalchemy/schema.py

     def _init_collections(self):
         pass
 
-
     @util.memoized_property
     def _autoincrement_column(self):
         for col in self.primary_key:
             if col.autoincrement and \
                 col.type._type_affinity is not None and \
                 issubclass(col.type._type_affinity, sqltypes.Integer) and \
-                (not col.foreign_keys or col.autoincrement=='ignore_fk') and \
+                (not col.foreign_keys or col.autoincrement == 'ignore_fk') and \
                 isinstance(col.default, (type(None), Sequence)) and \
                 (col.server_default is None or col.server_default.reflected):
                 return col
 
         if self.primary_key:
             table.primary_key._replace(self)
+            Table._autoincrement_column._reset(table)
         elif self.key in table.primary_key:
             raise exc.ArgumentError(
                 "Trying to redefine primary-key column '%s' as a "

lib/sqlalchemy/util/langhelpers.py

         obj.__dict__[self.__name__] = result = self.fget(obj)
         return result
 
+    def _reset(self, obj):
+        obj.__dict__.pop(self.__name__, None)
 
 class memoized_instancemethod(object):
     """Decorate a method memoize its return value.

test/sql/test_metadata.py

 from test.lib import fixtures
 from test.lib import testing
 from test.lib.testing import ComparesTables, AssertsCompiledSQL
-from test.lib.testing import eq_
+from test.lib.testing import eq_, is_
 
 class MetaDataTest(fixtures.TestBase, ComparesTables):
     def test_metadata_connect(self):
             assign2
         )
 
+    def test_autoincrement_replace(self):
+        m = MetaData()
+
+        t = Table('t', m,
+            Column('id', Integer, primary_key=True)
+        )
+
+        is_(t._autoincrement_column, t.c.id)
+
+        t = Table('t', m,
+            Column('id', Integer, primary_key=True),
+            extend_existing=True
+        )
+        is_(t._autoincrement_column, t.c.id)
+
 class SchemaTest(fixtures.TestBase, AssertsCompiledSQL):
 
     def test_default_schema_metadata_fk(self):
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.