Skip to content

Instantly share code, notes, and snippets.

@ggtools
Last active June 5, 2019 05:48
Show Gist options
  • Save ggtools/7e79574912bedb38e1593c689a93a5ac to your computer and use it in GitHub Desktop.
Save ggtools/7e79574912bedb38e1593c689a93a5ac to your computer and use it in GitHub Desktop.
Implementation of PostgreSQL values construct
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql.expression import FromClause
class values(FromClause):
named_with_column = True
def __init__(self, columns, *args, **kw):
self._column_args = columns
self.list = args
self.alias_name = self.name = kw.pop('alias_name', None)
def _populate_column_collection(self):
for c in self._column_args:
c._make_proxy(self)
# Original version, failing on datetime values
def render_literal_value_0(compiler, value, type_):
return compilier.render_literal_value(value, type_)
# Version 1: use a if/elif chain to manually convert the datetime
def render_literal_value_1(compiler, value, type_):
try:
return compilier.render_literal_value(value, type_)
expect NotImplementedError:
if isinstance(value, datetime.datetime):
return value.strftime("'%Y-%m-%d %H:%M:%S'::TIMESTAMP")
# Add other cases ad-libitum
else:
raise NotImplementedError("Don't know how to literal-quote value %r" % value)
# Version 2: use Cast to work around the problem passing the datetime as bind_params
def render_literal_value_2(compiler, value, type_):
try:
return compilier.render_literal_value(value, type_)
expect NotImplementedError:
return compiler.process(Cast(value, type_))
@compiles(values)
def compile_values(element, compiler, asfrom=False, **kw):
columns = element.columns
v = "VALUES %s" % ", ".join(
"(%s)" % ", ".join(
render_literal_value_0(compiler, elem, column.type)
for elem, column in zip(tup, columns))
for tup in element.list
)
if asfrom:
if element.alias_name:
v = "(%s) AS %s (%s)" % (v, element.alias_name, (", ".join(c.name for c in element.columns)))
else:
v = "(%s)" % v
return v
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment