.. change::
:tags: feature, sql
- :tickets: 2877
+ :tickets: 2877, 2882
New improvements to the :func:`.text` construct, including
more flexible ways to set up bound parameters and return types;
in particular, a :func:`.text` can now be turned into a full
FROM-object, embeddable in other statements as an alias or CTE
- using the new method :meth:`.TextClause.columns`.
+ using the new method :meth:`.TextClause.columns`. The :func:`.text`
+ construct can also render "inline" bound parameters when the construct
+ is compiled in a "literal bound" context.
.. seealso::
def post_process_text(self, text):
return text
- def visit_textclause(self, textclause, **kwargs):
+ def visit_textclause(self, textclause, **kw):
def do_bindparam(m):
name = m.group(1)
if name in textclause._bindparams:
- return self.process(textclause._bindparams[name])
+ return self.process(textclause._bindparams[name], **kw)
else:
- return self.bindparam_string(name, **kwargs)
+ return self.bindparam_string(name, **kw)
# un-escape any \:params
return BIND_PARAMS_ESC.sub(lambda m: m.group(1),
checkparams={'bar': 4, 'whee': 7},
)
+ def test_literal_binds(self):
+ t = text("select * from foo where lala=:bar and hoho=:whee")
+ t = t.bindparams(bindparam('bar', 4), whee='whee')
+
+ self.assert_compile(
+ t,
+ "select * from foo where lala=4 and hoho='whee'",
+ checkparams={},
+ literal_binds=True
+ )
+
def _assert_type_map(self, t, compare):
map_ = dict(
(b.key, b.type) for b in t._bindparams.values()