]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
String compiler can now literal compile datetime objects
authorFederico Caselli <cfederico87@gmail.com>
Tue, 24 Mar 2020 21:55:46 +0000 (22:55 +0100)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 29 Mar 2020 22:08:40 +0000 (18:08 -0400)
Add ability to literal compile a :class:`DateTime`, :class:`Date`
or :class:"Time" when using the string dialect for debugging purposes.
This change does not impact real dialect implementation that retain
their current behavior.

Fixes: #5052
Change-Id: Ia3fad2be905c6d35b0106b9a2388c7508f067e90

doc/build/changelog/unreleased_13/5052.rst [new file with mode: 0644]
lib/sqlalchemy/engine/default.py
test/sql/test_compiler.py
test/sql/test_types.py

diff --git a/doc/build/changelog/unreleased_13/5052.rst b/doc/build/changelog/unreleased_13/5052.rst
new file mode 100644 (file)
index 0000000..9680ba5
--- /dev/null
@@ -0,0 +1,8 @@
+.. change::
+    :tags: sql, types
+    :tickets: 5052
+
+    Add ability to literal compile a :class:`DateTime`, :class:`Date`
+    or :class:"Time" when using the string dialect for debugging purposes.
+    This change does not impact real dialect implementation that retain
+    their current behavior.
index d0940decf0c126968cbc05e5069aad71839b0df0..c44f07538e6c70c6386a748766ac885094304a05 100644 (file)
@@ -642,6 +642,26 @@ class DefaultDialect(interfaces.Dialect):
         return name
 
 
+class _RendersLiteral(object):
+    def literal_processor(self, dialect):
+        def process(value):
+            return "'%s'" % value
+
+        return process
+
+
+class _StrDateTime(_RendersLiteral, sqltypes.DateTime):
+    pass
+
+
+class _StrDate(_RendersLiteral, sqltypes.Date):
+    pass
+
+
+class _StrTime(_RendersLiteral, sqltypes.Time):
+    pass
+
+
 class StrCompileDialect(DefaultDialect):
 
     statement_compiler = compiler.StrSQLCompiler
@@ -658,6 +678,12 @@ class StrCompileDialect(DefaultDialect):
 
     supports_simple_order_by_label = True
 
+    colspecs = {
+        sqltypes.DateTime: _StrDateTime,
+        sqltypes.Date: _StrDate,
+        sqltypes.Time: _StrTime,
+    }
+
 
 class DefaultExecutionContext(interfaces.ExecutionContext):
     isinsert = False
index ef3e5d26e8597378806284b5a5e700ef27335ced..151ecb1d2527df53343bd4e855a261d122b6d341 100644 (file)
@@ -10,6 +10,7 @@ styling and coherent test organization.
 
 """
 
+import datetime
 import decimal
 
 from sqlalchemy import alias
@@ -3745,6 +3746,21 @@ class StringifySpecialTest(fixtures.TestBase):
             "WITHIN GROUP (ORDER BY mytable.name DESC) AS anon_1 FROM mytable",
         )
 
+    @testing.combinations(
+        ("datetime", datetime.datetime.now()),
+        ("date", datetime.date.today()),
+        ("time", datetime.time()),
+        argnames="value",
+        id_="ia",
+    )
+    def test_render_datetime(self, value):
+        lit = literal(value)
+
+        eq_ignore_whitespace(
+            str(lit.compile(compile_kwargs={"literal_binds": True})),
+            "'%s'" % value,
+        )
+
 
 class KwargPropagationTest(fixtures.TestBase):
     @classmethod
index 9fb79958da97a6d66113bdf06e5949c7a4ec6a5f..2af8cb325986aa773c92e531e56c0bfee107b142 100644 (file)
@@ -3237,3 +3237,26 @@ class CallableTest(fixtures.TestBase):
         )
         assert isinstance(thang_table.c.name.type, Unicode)
         thang_table.create()
+
+
+class LiteralTest(fixtures.TestBase):
+    __backend__ = True
+
+    @testing.combinations(
+        ("datetime", datetime.datetime.now()),
+        ("date", datetime.date.today()),
+        ("time", datetime.time()),
+        argnames="value",
+        id_="ia",
+    )
+    @testing.skip_if(lambda: testing.requires.datetime_literals)
+    def test_render_datetime(self, value):
+        lit = literal(value)
+
+        assert_raises_message(
+            NotImplementedError,
+            "Don't know how to literal-quote value.*",
+            lit.compile,
+            dialect=testing.db.dialect,
+            compile_kwargs={"literal_binds": True},
+        )