diff --git a/caravel/models.py b/caravel/models.py index 557190f32290..fb868d38926a 100644 --- a/caravel/models.py +++ b/caravel/models.py @@ -37,6 +37,8 @@ from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.orm import relationship from sqlalchemy.sql import table, literal_column, text, column +from sqlalchemy.sql.expression import ColumnClause +from sqlalchemy.ext.compiler import compiles from sqlalchemy_utils import EncryptedType import caravel @@ -655,6 +657,22 @@ def query( # sqla metrics_exprs = [] if granularity: + + # TODO: sqlalchemy 1.2 release should be doing this on its own. + # Patch only if the column clause is specific for DateTime set and + # granularity is selected. + @compiles(ColumnClause) + def _(element, compiler, **kw): + text = compiler.visit_column(element, **kw) + try: + if element.is_literal and hasattr(element.type, 'python_type') and \ + type(element.type) is DateTime: + + text = text.replace('%%', '%') + except NotImplementedError: + pass # Some elements raise NotImplementedError for python_type + return text + dttm_col = cols[granularity] dttm_expr = dttm_col.sqla_col.label('timestamp') timestamp = dttm_expr @@ -664,7 +682,7 @@ def query( # sqla if time_grain_sqla: udf = self.database.grains_dict().get(time_grain_sqla, '{col}') timestamp_grain = literal_column( - udf.function.format(col=dttm_expr)).label('timestamp') + udf.function.format(col=dttm_expr), type_=DateTime).label('timestamp') else: timestamp_grain = timestamp