]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Unwrap TIMESTAMP when doing an isinstance()
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 27 Jun 2019 17:25:12 +0000 (13:25 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 27 Jun 2019 21:51:28 +0000 (17:51 -0400)
Fixed bug where the special logic to render "NULL" for the
:class:`.TIMESTAMP` datatype when ``nullable=True`` would not work if the
column's datatype were a :class:`.TypeDecorator` or a :class:`.Variant`.
The logic now ensures that it unwraps down to the original
:class:`.TIMESTAMP` so that this special case NULL keyword is correctly
rendered when requested.

Fixes: #4743
Change-Id: I02b22dfa3db06daea37b044e2206a8569e2e5d22
(cherry picked from commit 401a2691fbeebd5a26341e732644584cb096bc58)

doc/build/changelog/unreleased_13/4743.rst [new file with mode: 0644]
lib/sqlalchemy/dialects/mysql/base.py
test/dialect/mysql/test_types.py

diff --git a/doc/build/changelog/unreleased_13/4743.rst b/doc/build/changelog/unreleased_13/4743.rst
new file mode 100644 (file)
index 0000000..0bac5dc
--- /dev/null
@@ -0,0 +1,10 @@
+.. change::
+    :tags: bug, mysql
+    :tickets: 4743
+
+    Fixed bug where the special logic to render "NULL" for the
+    :class:`.TIMESTAMP` datatype when ``nullable=True`` would not work if the
+    column's datatype were a :class:`.TypeDecorator` or a :class:`.Variant`.
+    The logic now ensures that it unwraps down to the original
+    :class:`.TIMESTAMP` so that this special case NULL keyword is correctly
+    rendered when requested.
index bfd1693d97c74a7615f93e531ea7f3d2e7167448..e79327b2b8ce78ab8ef649629d863bd8cee1ba90 100644 (file)
@@ -1499,7 +1499,10 @@ class MySQLDDLCompiler(compiler.DDLCompiler):
             ),
         ]
 
-        is_timestamp = isinstance(column.type, sqltypes.TIMESTAMP)
+        is_timestamp = isinstance(
+            column.type._unwrapped_dialect_impl(self.dialect),
+            sqltypes.TIMESTAMP,
+        )
 
         if not column.nullable:
             colspec.append("NOT NULL")
index 2801c800b1bf5bea46368acb8078f1158105fd3f..86e4b13a08810f5a3ac08d39a0308bc93060d66e 100644 (file)
@@ -1,5 +1,4 @@
 # coding: utf-8
-
 from collections import OrderedDict
 import datetime
 import decimal
@@ -19,6 +18,7 @@ from sqlalchemy import String
 from sqlalchemy import Table
 from sqlalchemy import testing
 from sqlalchemy import TIMESTAMP
+from sqlalchemy import TypeDecorator
 from sqlalchemy import types as sqltypes
 from sqlalchemy import UnicodeText
 from sqlalchemy import util
@@ -667,14 +667,27 @@ class TypesTest(
             Table("t", MetaData(), c)
             self.assert_compile(schema.CreateColumn(c), "t %s" % expected)
 
+    def test_timestamp_nullable_plain(self):
+        self._test_timestamp_nullable(TIMESTAMP)
+
+    def test_timestamp_nullable_typedecorator(self):
+        class MyTime(TypeDecorator):
+            impl = TIMESTAMP
+
+        self._test_timestamp_nullable(MyTime())
+
+    def test_timestamp_nullable_variant(self):
+        t = String().with_variant(TIMESTAMP, "mysql")
+        self._test_timestamp_nullable(t)
+
     @testing.requires.mysql_zero_date
     @testing.provide_metadata
-    def test_timestamp_nullable(self):
+    def _test_timestamp_nullable(self, type_):
         ts_table = Table(
             "mysql_timestamp",
             self.metadata,
-            Column("t1", TIMESTAMP),
-            Column("t2", TIMESTAMP, nullable=False),
+            Column("t1", type_),
+            Column("t2", type_, nullable=False),
             mysql_engine="InnoDB",
         )
         self.metadata.create_all()