diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2014-01-22 15:38:00 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2014-01-22 15:38:00 -0500 |
| commit | 1732414076677e8fb84134325635729691f3d26d (patch) | |
| tree | d77745e4843f03d5412cb3f2bff3435ca88bd7ee | |
| parent | ee1f4d21037690ad996c5eacf7e1200e92f2fbaa (diff) | |
| download | sqlalchemy-1732414076677e8fb84134325635729691f3d26d.tar.gz | |
- Added new test coverage for so-called "down adaptions" of SQL types,
where a more specific type is adapted to a more generic one - this
use case is needed by some third party tools such as ``sqlacodegen``.
The specific cases that needed repair within this test suite were that
of :class:`.mysql.ENUM` being downcast into a :class:`.types.Enum`,
and that of SQLite date types being cast into generic date types.
The ``adapt()`` method needed to become more specific here to counteract
the removal of a "catch all" ``**kwargs`` collection on the base
:class:`.TypeEngine` class that was removed in 0.9. [ticket:2917]
| -rw-r--r-- | doc/build/changelog/changelog_09.rst | 14 | ||||
| -rw-r--r-- | lib/sqlalchemy/dialects/mysql/base.py | 7 | ||||
| -rw-r--r-- | lib/sqlalchemy/dialects/sqlite/base.py | 11 | ||||
| -rw-r--r-- | test/sql/test_types.py | 22 |
4 files changed, 43 insertions, 11 deletions
diff --git a/doc/build/changelog/changelog_09.rst b/doc/build/changelog/changelog_09.rst index d59f3ec60..768326528 100644 --- a/doc/build/changelog/changelog_09.rst +++ b/doc/build/changelog/changelog_09.rst @@ -15,6 +15,20 @@ :version: 0.9.2 .. change:: + :tags: bug, mysql, sql + :tickets: 2917 + + Added new test coverage for so-called "down adaptions" of SQL types, + where a more specific type is adapted to a more generic one - this + use case is needed by some third party tools such as ``sqlacodegen``. + The specific cases that needed repair within this test suite were that + of :class:`.mysql.ENUM` being downcast into a :class:`.types.Enum`, + and that of SQLite date types being cast into generic date types. + The ``adapt()`` method needed to become more specific here to counteract + the removal of a "catch all" ``**kwargs`` collection on the base + :class:`.TypeEngine` class that was removed in 0.9. + + .. change:: :tags: feature, sql :tickets: 2910 diff --git a/lib/sqlalchemy/dialects/mysql/base.py b/lib/sqlalchemy/dialects/mysql/base.py index e45f6ecd8..61698b038 100644 --- a/lib/sqlalchemy/dialects/mysql/base.py +++ b/lib/sqlalchemy/dialects/mysql/base.py @@ -1189,9 +1189,10 @@ class ENUM(sqltypes.Enum, _EnumeratedValues): return value return process - def adapt(self, impltype, **kw): - kw['strict'] = self.strict - return sqltypes.Enum.adapt(self, impltype, **kw) + def adapt(self, cls, **kw): + if issubclass(cls, ENUM): + kw['strict'] = self.strict + return sqltypes.Enum.adapt(self, cls, **kw) class SET(_EnumeratedValues): diff --git a/lib/sqlalchemy/dialects/sqlite/base.py b/lib/sqlalchemy/dialects/sqlite/base.py index 579a61046..d8aa58c2c 100644 --- a/lib/sqlalchemy/dialects/sqlite/base.py +++ b/lib/sqlalchemy/dialects/sqlite/base.py @@ -154,11 +154,12 @@ class _DateTimeMixin(object): self._storage_format = storage_format def adapt(self, cls, **kw): - if self._storage_format: - kw["storage_format"] = self._storage_format - if self._reg: - kw["regexp"] = self._reg - return util.constructor_copy(self, cls, **kw) + if issubclass(cls, _DateTimeMixin): + if self._storage_format: + kw["storage_format"] = self._storage_format + if self._reg: + kw["regexp"] = self._reg + return super(_DateTimeMixin, self).adapt(cls, **kw) def literal_processor(self, dialect): bp = self.bind_processor(dialect) diff --git a/test/sql/test_types.py b/test/sql/test_types.py index 3a263aab2..3df19874b 100644 --- a/test/sql/test_types.py +++ b/test/sql/test_types.py @@ -114,21 +114,37 @@ class AdaptTest(fixtures.TestBase): """ - for typ in self._all_types(): + def adaptions(): + for typ in self._all_types(): + up_adaptions = [typ] + typ.__subclasses__() + yield False, typ, up_adaptions + for subcl in typ.__subclasses__(): + if subcl is not typ and \ + typ is not TypeDecorator and \ + "sqlalchemy" in subcl.__module__: + yield True, subcl, [typ] + + for is_down_adaption, typ, target_adaptions in adaptions(): if typ in (types.TypeDecorator, types.TypeEngine, types.Variant): continue elif typ is dialects.postgresql.ARRAY: t1 = typ(String) else: t1 = typ() - for cls in [typ] + typ.__subclasses__(): + for cls in target_adaptions: if not issubclass(typ, types.Enum) and \ issubclass(cls, types.Enum): continue + + # print("ADAPT %s -> %s" % (t1.__class__, cls)) t2 = t1.adapt(cls) assert t1 is not t2 + + if is_down_adaption: + t2, t1 = t1, t2 + for k in t1.__dict__: - if k == 'impl': + if k in ('impl', '_is_oracle_number'): continue # assert each value was copied, or that # the adapted type has a more specific |
