summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/build/changelog/unreleased_13/5052.rst8
-rw-r--r--lib/sqlalchemy/engine/default.py26
-rw-r--r--test/sql/test_compiler.py16
-rw-r--r--test/sql/test_types.py23
4 files changed, 73 insertions, 0 deletions
diff --git a/doc/build/changelog/unreleased_13/5052.rst b/doc/build/changelog/unreleased_13/5052.rst
new file mode 100644
index 000000000..9680ba5db
--- /dev/null
+++ b/doc/build/changelog/unreleased_13/5052.rst
@@ -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.
diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py
index d0940decf..c44f07538 100644
--- a/lib/sqlalchemy/engine/default.py
+++ b/lib/sqlalchemy/engine/default.py
@@ -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
diff --git a/test/sql/test_compiler.py b/test/sql/test_compiler.py
index ef3e5d26e..151ecb1d2 100644
--- a/test/sql/test_compiler.py
+++ b/test/sql/test_compiler.py
@@ -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
diff --git a/test/sql/test_types.py b/test/sql/test_types.py
index 9fb79958d..2af8cb325 100644
--- a/test/sql/test_types.py
+++ b/test/sql/test_types.py
@@ -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},
+ )