summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2012-09-23 12:51:24 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2012-09-23 12:51:24 -0400
commit152163b3336970460b605fc2a79766d94f467f8d (patch)
treea5e1014cdb244ee792ccdf7447a61b747d1bb7f1
parente354dd10f8c3cc19e9cb3a6536f98798ba3538f1 (diff)
downloadsqlalchemy-152163b3336970460b605fc2a79766d94f467f8d.tar.gz
- [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]
-rw-r--r--CHANGES6
-rw-r--r--lib/sqlalchemy/schema.py24
-rw-r--r--lib/sqlalchemy/util/langhelpers.py2
-rw-r--r--test/sql/test_metadata.py17
4 files changed, 37 insertions, 12 deletions
diff --git a/CHANGES b/CHANGES
index be72bcab7..3e1668584 100644
--- a/CHANGES
+++ b/CHANGES
@@ -827,6 +827,12 @@ are also present in 0.8.
operators are present as methods like all
the other operators. [ticket:2544]
+ - [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]
- engine
- [bug] Fixed bug whereby
diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py
index fdff37d3f..d7720a867 100644
--- a/lib/sqlalchemy/schema.py
+++ b/lib/sqlalchemy/schema.py
@@ -464,14 +464,13 @@ class Table(SchemaItem, expression.TableClause):
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
@@ -1038,6 +1037,7 @@ class Column(SchemaItem, expression.ColumnClause):
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 "
@@ -1051,7 +1051,8 @@ class Column(SchemaItem, expression.ColumnClause):
"The 'index' keyword argument on Column is boolean only. "
"To create indexes with a specific name, create an "
"explicit Index object external to the Table.")
- Index(expression._truncated_label('ix_%s' % self._label), self, unique=self.unique)
+ Index(expression._truncated_label('ix_%s' % self._label),
+ self, unique=self.unique)
elif self.unique:
if isinstance(self.unique, basestring):
raise exc.ArgumentError(
@@ -1082,10 +1083,10 @@ class Column(SchemaItem, expression.ColumnClause):
c = self._constructor(
name=self.name,
type_=self.type,
- key = self.key,
- primary_key = self.primary_key,
- nullable = self.nullable,
- unique = self.unique,
+ key=self.key,
+ primary_key=self.primary_key,
+ nullable=self.nullable,
+ unique=self.unique,
quote=self.quote,
index=self.index,
autoincrement=self.autoincrement,
@@ -1118,10 +1119,11 @@ class Column(SchemaItem, expression.ColumnClause):
c = self._constructor(
expression._as_truncated(name or self.name),
self.type,
- key = key if key else name if name else self.key,
- primary_key = self.primary_key,
- nullable = self.nullable,
- quote=self.quote, _proxies=[self], *fk)
+ key=key if key else name if name else self.key,
+ primary_key=self.primary_key,
+ nullable=self.nullable,
+ quote=self.quote,
+ _proxies=[self], *fk)
except TypeError, e:
# Py3K
#raise TypeError(
diff --git a/lib/sqlalchemy/util/langhelpers.py b/lib/sqlalchemy/util/langhelpers.py
index ac4b5527a..7fe5d3e82 100644
--- a/lib/sqlalchemy/util/langhelpers.py
+++ b/lib/sqlalchemy/util/langhelpers.py
@@ -537,6 +537,8 @@ class memoized_property(object):
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.
diff --git a/test/sql/test_metadata.py b/test/sql/test_metadata.py
index c7321d7d9..dcf9820cc 100644
--- a/test/sql/test_metadata.py
+++ b/test/sql/test_metadata.py
@@ -13,7 +13,7 @@ import sqlalchemy as tsa
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):
@@ -721,6 +721,21 @@ class TableTest(fixtures.TestBase, AssertsCompiledSQL):
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):