]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- update the literal binds section
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 30 Jul 2014 20:08:33 +0000 (16:08 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 30 Jul 2014 20:08:33 +0000 (16:08 -0400)
doc/build/faq.rst

index 0c8314cb5de6d2edbde8176b6398cf39cd32bdc1..3dc81026b1ad6c9b8a7c84f934f1d4dd6cc33ccb 100644 (file)
@@ -251,19 +251,19 @@ How do I render SQL expressions as strings, possibly with bound parameters inlin
 The "stringification" of a SQLAlchemy statement or Query in the vast majority
 of cases is as simple as::
 
-    print str(statement)
+    print(str(statement))
 
 this applies both to an ORM :class:`~.orm.query.Query` as well as any :func:`.select` or other
 statement.   Additionally, to get the statement as compiled to a
 specific dialect or engine, if the statement itself is not already
 bound to one you can pass this in to :meth:`.ClauseElement.compile`::
 
-    print statement.compile(someengine)
+    print(statement.compile(someengine))
 
 or without an :class:`.Engine`::
 
     from sqlalchemy.dialects import postgresql
-    print statement.compile(dialect=postgresql.dialect())
+    print(statement.compile(dialect=postgresql.dialect()))
 
 When given an ORM :class:`~.orm.query.Query` object, in order to get at the
 :meth:`.ClauseElement.compile`
@@ -271,7 +271,7 @@ method we only need access the :attr:`~.orm.query.Query.statement`
 accessor first::
 
     statement = query.statement
-    print statement.compile(someengine)
+    print(statement.compile(someengine))
 
 The above forms will render the SQL statement as it is passed to the Python
 :term:`DBAPI`, which includes that bound parameters are not rendered inline.
@@ -289,60 +289,41 @@ flag, passed to ``compile_kwargs``::
 
     s = select([t]).where(t.c.x == 5)
 
-    print s.compile(compile_kwargs={"literal_binds": True})
+    print(s.compile(compile_kwargs={"literal_binds": True}))
 
 the above approach has the caveats that it is only supported for basic
 types, such as ints and strings, and furthermore if a :func:`.bindparam`
 without a pre-set value is used directly, it won't be able to
-stringify that either.    Additionally, the ``compile_kwargs`` argument
-itself is only available as of SQLAlchemy 0.9; and there are slightly
-more verbose ways of getting ``literal_binds`` injected with 0.8.
+stringify that either.
 
-.. topic::  Applying compiler kw arguments prior to 0.9
+To support inline literal rendering for types not supported, implement
+a :class:`.TypeDecorator` for the target type which includes a
+:meth:`.TypeDecorator.process_literal_param` method::
 
-    We can provide a fixed set of ``**kw`` by calling upon ``process()``
-    directly::
+    from sqlalchemy import TypeDecorator, Integer
 
-        compiled = s.compile()
-        print compiled.process(s, literal_binds=True)
 
-    Note that in this approach the statement is actually being stringified
-    twice, hence using ``compile_kwargs`` in 0.9 should be preferred.
+    class MyFancyType(TypeDecorator):
+        impl = Integer
 
+        def process_literal_param(self, value, dialect):
+            return "my_fancy_formatting(%s)" % value
 
-If we want to skip using ``literal_binds`` altogether due to the above
-caveats, we can take the approach of replacing them out ahead of time
-with whatever we want::
+    from sqlalchemy import Table, Column, MetaData
 
-    from sqlalchemy.sql import visitors, text
+    tab = Table('mytable', MetaData(), Column('x', MyFancyType()))
 
-    def replace_bindparam(element):
-        if hasattr(element, 'effective_value'):
-            return text(str(element.effective_value))
-
-    s = visitors.replacement_traverse(s, {}, replace_bindparam)
-    print s
-
-Still another approach to injecting functionality where bound
-parameters are concerned is to use the :doc:`Compilation Extension
-API <core/compiler>`::
-
-    from sqlalchemy.ext.compiler import compiles
-    from sqlalchemy.sql.expression import BindParameter
-
-    s = select([t]).where(t.c.x == 5)
+    print(
+        tab.select().where(tab.c.x > 5).compile(
+            compile_kwargs={"literal_binds": True})
+    )
 
-    @compiles(BindParameter)
-    def as_str(element, compiler, **kw):
-        if 'binds_as_str' in kw:
-            return str(element.effective_value)
-        else:
-            return compiler.visit_bindparam(element, **kw)
+producing output like::
 
-    print s.compile(compile_kwargs={"binds_as_str": True})
+    SELECT mytable.x
+    FROM mytable
+    WHERE mytable.x > my_fancy_formatting(5)
 
-Above, we pass a self-defined flag ``binds_as_str`` through the compiler,
-which we then intercept within our custom render method for :class:`.BindParameter`.
 
 Why does ``.col.in_([])`` Produce ``col != col``? Why not ``1=0``?
 -------------------------------------------------------------------