# Buggy code
def execute_query(self, query, data_source_id, metadata):
    signal.signal(signal.SIGINT, signal_handler)
    start_time = time.time()

    logger.info("Loading data source (%d)...", data_source_id)

    # TODO: we should probably cache data sources in Redis
    data_source = models.DataSource.get_by_id(data_source_id)

    self.update_state(
        state="STARTED", meta={"start_time": start_time, "custom_message": ""}
    )

    logger.info("Executing query:\n%s", query)

    query_hash = gen_query_hash(query)
    query_runner = get_query_runner(data_source.type, data_source.options)

    if query_runner.annotate_query():
        metadata["Task ID"] = self.request.id
        metadata["Query Hash"] = query_hash
        metadata["Queue"] = self.request.delivery_info["routing_key"]

        annotation = ", ".join(["{}: {}".format(k, v) for k, v in metadata.iteritems()])

        logging.debug("Annotation: %s", annotation)

        annotated_query = "/* {} */ {}".format(annotation, query)
    else:
        annotated_query = query

    with statsd_client.timer(
        "query_runner.{}.{}.run_time".format(data_source.type, data_source.name)
    ):
        data, error = query_runner.run_query(annotated_query)

    run_time = time.time() - start_time
    logger.info("Query finished... data length=%s, error=%s", data and len(data), error)

    self.update_state(
        state="STARTED",
        meta={"start_time": start_time, "error": error, "custom_message": ""},
    )

    # Delete query_hash
    redis_connection.delete(QueryTask._job_lock_id(query_hash, data_source.id))

    if not error:
        query_result, updated_query_ids = models.QueryResult.store_result(
            data_source.org_id,
            data_source.id,
            query_hash,
            query,
            data,
            run_time,
            utils.utcnow(),
        )
        for query_id in updated_query_ids:
            check_alerts_for_query.delay(query_id)
    else:
        raise QueryExecutionError(error)

    return query_result.id


# Traceback (DataError)
[2016-01-21 17:58:21,655][PID:12][ERROR][redash.wsgi] Exception on /api/users/2 [POST]
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/usr/local/lib/python2.7/dist-packages/flask_restful/__init__.py", line 477, in wrapper
resp = resource(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/flask_login.py", line 792, in decorated_view
return func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/flask/views.py", line 84, in view
return self.dispatch_request(*args, **kwargs)
File "/opt/redash/redash/handlers/base.py", line 19, in dispatch_request
return super(BaseResource, self).dispatch_request(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/flask_restful/__init__.py", line 587, in dispatch_request
resp = meth(*args, **kwargs)
File "/opt/redash/redash/handlers/users.py", line 76, in post
user.update_instance(**params)
File "/opt/redash/redash/models.py", line 106, in update_instance
self.save(only=self.dirty_fields)
File "/opt/redash/redash/models.py", line 93, in save
super(BaseModel, self).save(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/peewee.py", line 4146, in save
rows = self.update(**field_dict).where(self._pk_expr()).execute()
File "/usr/local/lib/python2.7/dist-packages/peewee.py", line 2751, in execute
return self.database.rows_affected(self._execute())
File "/opt/redash/redash/metrics/database.py", line 50, in metered_execute
result = real_execute(self, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/peewee.py", line 2371, in _execute
return self.database.execute_sql(sql, params, self.require_commit)
File "/opt/redash/redash/metrics/database.py", line 22, in execute_sql
result = super(MeteredPostgresqlExtDatabase, self).execute_sql(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/playhouse/postgres_ext.py", line 369, in execute_sql
self.commit()
File "/usr/local/lib/python2.7/dist-packages/peewee.py", line 2922, in __exit__
reraise(new_type, new_type(*exc_value.args), traceback)
File "/usr/local/lib/python2.7/dist-packages/playhouse/postgres_ext.py", line 360, in execute_sql
cursor.execute(sql, params or ())
DataError: invalid input syntax for integer: "admin"
LINE 1: ..." = E'foo@bar.com', "groups" = ARRAY[2, E'admin'] ...

# Fixed code
def execute_query(self, query, data_source_id, metadata):
    signal.signal(signal.SIGINT, signal_handler)
    start_time = time.time()

    logger.info("task=execute_query state=load_ds ds_id=%d", data_source_id)

    data_source = models.DataSource.get_by_id(data_source_id)

    self.update_state(
        state="STARTED", meta={"start_time": start_time, "custom_message": ""}
    )

    logger.debug("Executing query:\n%s", query)

    query_hash = gen_query_hash(query)
    query_runner = get_query_runner(data_source.type, data_source.options)

    logger.info(
        "task=execute_query state=before query_hash=%s type=%s ds_id=%d task_id=%s queue=%s query_id=%s username=%s",
        query_hash,
        data_source.type,
        data_source.id,
        self.request.id,
        self.request.delivery_info["routing_key"],
        metadata.get("Query ID", "unknown"),
        metadata.get("Username", "unknown"),
    )

    if query_runner.annotate_query():
        metadata["Task ID"] = self.request.id
        metadata["Query Hash"] = query_hash
        metadata["Queue"] = self.request.delivery_info["routing_key"]

        annotation = ", ".join(["{}: {}".format(k, v) for k, v in metadata.iteritems()])

        logging.debug("Annotation: %s", annotation)

        annotated_query = "/* {} */ {}".format(annotation, query)
    else:
        annotated_query = query

    with statsd_client.timer(
        "query_runner.{}.{}.run_time".format(data_source.type, data_source.name)
    ):
        data, error = query_runner.run_query(annotated_query)

    logger.info(
        "task=execute_query state=after query_hash=%s type=%s ds_id=%d task_id=%s queue=%s query_id=%s username=%s",
        query_hash,
        data_source.type,
        data_source.id,
        self.request.id,
        self.request.delivery_info["routing_key"],
        metadata.get("Query ID", "unknown"),
        metadata.get("Username", "unknown"),
    )

    run_time = time.time() - start_time
    logger.info("Query finished... data length=%s, error=%s", data and len(data), error)

    self.update_state(
        state="STARTED",
        meta={"start_time": start_time, "error": error, "custom_message": ""},
    )

    # Delete query_hash
    redis_connection.delete(QueryTask._job_lock_id(query_hash, data_source.id))

    if not error:
        query_result, updated_query_ids = models.QueryResult.store_result(
            data_source.org_id,
            data_source.id,
            query_hash,
            query,
            data,
            run_time,
            utils.utcnow(),
        )
        logger.info(
            "task=execute_query state=after_store query_hash=%s type=%s ds_id=%d task_id=%s queue=%s query_id=%s username=%s",
            query_hash,
            data_source.type,
            data_source.id,
            self.request.id,
            self.request.delivery_info["routing_key"],
            metadata.get("Query ID", "unknown"),
            metadata.get("Username", "unknown"),
        )
        for query_id in updated_query_ids:
            check_alerts_for_query.delay(query_id)
        logger.info(
            "task=execute_query state=after_alerts query_hash=%s type=%s ds_id=%d task_id=%s queue=%s query_id=%s username=%s",
            query_hash,
            data_source.type,
            data_source.id,
            self.request.id,
            self.request.delivery_info["routing_key"],
            metadata.get("Query ID", "unknown"),
            metadata.get("Username", "unknown"),
        )
    else:
        raise QueryExecutionError(error)

    return query_result.id