]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Reflect decimal points in MariaDB non-quoted numeric defaults
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 3 Dec 2020 16:17:08 +0000 (11:17 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 3 Dec 2020 16:17:08 +0000 (11:17 -0500)
Fixed issue where reflecting a server default on MariaDB only that
contained a decimal point in the value would fail to be reflected
correctly, leading towards a reflected table that lacked any server
default.

Fixes: #5744
Change-Id: Ifc5960928685a906558ba84ed6f59eecb3b1c358

doc/build/changelog/unreleased_13/5744.rst [new file with mode: 0644]
lib/sqlalchemy/dialects/mysql/reflection.py
test/dialect/mysql/test_reflection.py

diff --git a/doc/build/changelog/unreleased_13/5744.rst b/doc/build/changelog/unreleased_13/5744.rst
new file mode 100644 (file)
index 0000000..7325279
--- /dev/null
@@ -0,0 +1,10 @@
+.. change::
+    :tags: bug, mysql, reflection
+    :tickets: 5744
+    :versions: 1.4.0b2
+
+    Fixed issue where reflecting a server default on MariaDB only that
+    contained a decimal point in the value would fail to be reflected
+    correctly, leading towards a reflected table that lacked any server
+    default.
+
index 5be6a010e9d056d35741773bb412c47ac0ed51f4..14fb97c645797ab6e5418a5887377451862debee 100644 (file)
@@ -381,8 +381,8 @@ class MySQLTableDefinitionParser(object):
             r"(?: +COLLATE +(?P<collate>[\w_]+))?"
             r"(?: +(?P<notnull>(?:NOT )?NULL))?"
             r"(?: +DEFAULT +(?P<default>"
-            r"(?:NULL|'(?:''|[^'])*'|[\w\(\)]+"
-            r"(?: +ON UPDATE [\w\(\)]+)?)"
+            r"(?:NULL|'(?:''|[^'])*'|[\w\.\(\)]+"
+            r"(?: +ON UPDATE [\w\.\(\)]+)?)"
             r"))?"
             r"(?: +(?:GENERATED ALWAYS)? ?AS +(?P<generated>\("
             r".*\))? ?(?P<persistence>VIRTUAL|STORED)?)?"
index d5684b22f62382ebec0bf28adaf1494f35b2c53b..3871dbecca7dfa241dc875863c25f80b33255655 100644 (file)
@@ -234,6 +234,9 @@ class ReflectionTest(fixtures.TestBase, AssertsCompiledSQL):
     def test_default_reflection(self):
         """Test reflection of column defaults."""
 
+        # TODO: this test is a mess.   should be broken into individual
+        # combinations
+
         from sqlalchemy.dialects.mysql import VARCHAR
 
         def_table = Table(
@@ -258,6 +261,8 @@ class ReflectionTest(fixtures.TestBase, AssertsCompiledSQL):
                     )
                 ),
             ),
+            Column("c7", mysql.DOUBLE(), DefaultClause("0.0000")),
+            Column("c8", mysql.DOUBLE(22, 6), DefaultClause("0.0000")),
         )
 
         def_table.create(testing.db)
@@ -280,6 +285,15 @@ class ReflectionTest(fixtures.TestBase, AssertsCompiledSQL):
         assert reflected.c.c5.default is None
         assert reflected.c.c5.server_default is None
         assert reflected.c.c6.default is None
+        assert str(reflected.c.c7.server_default.arg) in ("0", "'0'")
+
+        # this is because the numeric is 6 decimal places, MySQL
+        # formats it to that many places.
+        assert str(reflected.c.c8.server_default.arg) in (
+            "0.000000",
+            "'0.000000'",
+        )
+
         assert re.match(
             r"CURRENT_TIMESTAMP(\(\))? ON UPDATE CURRENT_TIMESTAMP(\(\))?",
             str(reflected.c.c6.server_default.arg).upper(),
@@ -300,6 +314,11 @@ class ReflectionTest(fixtures.TestBase, AssertsCompiledSQL):
         assert reflected.c.c5.default is None
         assert reflected.c.c5.server_default is None
         assert reflected.c.c6.default is None
+        assert str(reflected.c.c7.server_default.arg) in ("0", "'0'")
+        assert str(reflected.c.c8.server_default.arg) in (
+            "0.000000",
+            "'0.000000'",
+        )
         assert re.match(
             r"CURRENT_TIMESTAMP(\(\))? ON UPDATE CURRENT_TIMESTAMP(\(\))?",
             str(reflected.c.c6.server_default.arg).upper(),