# Buggy code
def _extract_filters(self, queryparams=None):
    """Extracts filters from QueryString parameters."""
    if not queryparams:
        queryparams = self.request.GET

    filters = []

    for param, paramvalue in queryparams.items():
        param = param.strip()

        # Ignore specific fields
        if param.startswith("_") and param not in ("_since", "_to", "_before"):
            continue

        # Handle the _since specific filter.
        if param in ("_since", "_to", "_before"):
            value = native_value(paramvalue.strip('"'))

            if not isinstance(value, six.integer_types):
                error_details = {
                    "name": param,
                    "location": "querystring",
                    "description": "Invalid value for %s" % param,
                }
                raise_invalid(self.request, **error_details)

            if param == "_since":
                operator = COMPARISON.GT
            else:
                if param == "_to":
                    message = "_to is now deprecated, you should use _before instead"
                    url = (
                        "http://cliquet.rtfd.org/en/2.4.0/api/resource"
                        ".html#list-of-available-url-parameters"
                    )
                    send_alert(self.request, message, url)
                operator = COMPARISON.LT
            filters.append(Filter(self.model.modified_field, value, operator))
            continue

        m = re.match(r"^(min|max|not|lt|gt|in|exclude)_(\w+)$", param)
        if m:
            keyword, field = m.groups()
            operator = getattr(COMPARISON, keyword.upper())
        else:
            operator, field = COMPARISON.EQ, param

        if not self.is_known_field(field):
            error_details = {
                "location": "querystring",
                "description": "Unknown filter field '{0}'".format(param),
            }
            raise_invalid(self.request, **error_details)

        value = native_value(paramvalue)
        if operator in (COMPARISON.IN, COMPARISON.EXCLUDE):
            value = set([native_value(v) for v in paramvalue.split(",")])

        filters.append(Filter(field, value, operator))

    return filters


# Traceback (BackendError)
{"Pid":4280,"EnvVersion":"2.0","Hostname":"ip-172-31-4-126","Timestamp":1462794460764000000,"Fields":{"lang":null,"exception":"Traceback (most recent call last):
File \"\/data\/kinto-dist\/lib\/python2.7\/site-packages\/pyramid\/tweens.py\", line 20, in excview_tween
response = handler(request)
File \"\/data\/kinto-dist\/lib\/python2.7\/site-packages\/pyramid_tm\/__init__.py\", line 101, in tm_tween
reraise(*exc_info)
File \"\/data\/kinto-dist\/lib\/python2.7\/site-packages\/pyramid_tm\/__init__.py\", line 83, in tm_tween
response = handler(request)
File \"\/data\/kinto-dist\/lib\/python2.7\/site-packages\/pyramid\/router.py\", line 145, in handle_request
view_name
File \"\/data\/kinto-dist\/lib\/python2.7\/site-packages\/pyramid\/view.py\", line 541, in _call_view
response = view_callable(context, request)
File \"\/data\/kinto-dist\/lib\/python2.7\/site-packages\/pyramid\/config\/views.py\", line 602, in __call__
return view(context, request)
File \"\/data\/kinto-dist\/lib\/python2.7\/site-packages\/pyramid\/config\/views.py\", line 328, in attr_view
return view(context, request)
File \"\/data\/kinto-dist\/lib\/python2.7\/site-packages\/pyramid\/config\/views.py\", line 304, in predicate_wrapper
return view(context, request)
File \"\/data\/kinto-dist\/lib\/python2.7\/site-packages\/pyramid\/config\/views.py\", line 244, in _secured_view
return view(context, request)
File \"\/data\/kinto-dist\/lib\/python2.7\/site-packages\/pyramid\/config\/views.py\", line 353, in rendered_view
result = view(context, request)
File \"\/data\/kinto-dist\/lib\/python2.7\/site-packages\/pyramid\/config\/views.py\", line 507, in _requestonly_view
response = view(request)
File \"\/data\/kinto-dist\/lib\/python2.7\/site-packages\/cornice\/service.py\", line 571, in wrapper
response = view_()
File \"\/data\/kinto-dist\/lib\/python2.7\/site-packages\/kinto\/views\/records.py\", line 76, in collection_get
result = super(Record, self).collection_get()
File \"\/data\/kinto-dist\/lib\/python2.7\/site-packages\/cliquet\/resource\/__init__.py\", line 240, in collection_get
include_deleted=include_deleted)
File \"\/data\/kinto-dist\/lib\/python2.7\/site-packages\/cliquet\/resource\/model.py\", line 104, in get_records
auth=self.auth)
File \"\/data\/kinto-dist\/lib\/python2.7\/site-packages\/cliquet\/storage\/postgresql\/__init__.py\", line 538, in get_all
retrieved = result.fetchmany(self._max_fetch_size)
File \"\/usr\/lib64\/python2.7\/contextlib.py\", line 35, in __exit__
self.gen.throw(type, value, traceback)
File \"\/data\/kinto-dist\/lib\/python2.7\/site-packages\/cliquet\/storage\/postgresql\/client.py\", line 53, in connect
raise exceptions.BackendError(original=e)
BackendError: ProgrammingError: (psycopg2.ProgrammingError) operator does not exist: text <> integer
LINE 7:                AND id NOT IN (1)
^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.
[SQL: '\
WITH total_filtered AS (\
SELECT COUNT(id) AS count\
FROM records\
WHERE parent_id = %(parent_id)s\
AND collection_id = %(collection_id)s\
AND id NOT IN %(filters_value_0)s\
),\
collection_filtered AS (\
SELECT id, last_modified, data\
FROM records\
WHERE parent_id = %(parent_id)s\
AND collection_id = %(collection_id)s\
AND id NOT IN %(filters_value_0)s\
LIMIT 10000\
),\
fake_deleted AS (\
SELECT (%(deleted_field)s)::JSONB AS data\
),\
filtered_deleted AS (\
SELECT id, last_modified, fake_deleted.data AS data\
FROM deleted, fake_deleted\
WHERE parent_id = %(parent_id)s\
AND collection_id = %(collection_id)s\
AND id NOT IN %(filters_value_0)s\
LIMIT 0\
),\
all_records AS (\
SELECT * FROM filtered_deleted\
UNION ALL\
SELECT * FROM collection_filtered\
),\
paginated_records AS (\
SELECT DISTINCT id\
FROM all_records\
\
)\
SELECT total_filtered.count AS count_total,\
a.id, as_epoch(a.last_modified) AS last_modified, a.data\
FROM paginated_records AS p JOIN all_records AS a ON (a.id = p.id),\
total_filtered\
ORDER BY last_modified DESC\
;\
'] [parameters: {'collection_id': 'record', 'deleted_field': '{\"deleted\":true}', 'parent_id': u'\/buckets\/blocklists\/collections\/certificates', 'filters_value_0': (1,)}]","uid":null,"errno":null,"querystring":"{\"exclude_id\":\"1\"}","agent":"Amazon CloudFront","method":"GET","collection_id":"record","path":"\/v1\/buckets\/blocklists\/collections\/certificates\/records","authn_type":null,"collection_timestamp":1461920076590},"Logger":"kinto","Type":["(psycopg2.ProgrammingError) operator does not exist: text <> integer
LINE 7:                AND id NOT IN (1)
^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.
"],"Severity":0}

# Fixed code
def _extract_filters(self, queryparams=None):
    """Extracts filters from QueryString parameters."""
    if not queryparams:
        queryparams = self.request.GET

    filters = []

    for param, paramvalue in queryparams.items():
        param = param.strip()

        error_details = {
            "name": param,
            "location": "querystring",
            "description": "Invalid value for %s" % param,
        }

        # Ignore specific fields
        if param.startswith("_") and param not in ("_since", "_to", "_before"):
            continue

        # Handle the _since specific filter.
        if param in ("_since", "_to", "_before"):
            value = native_value(paramvalue.strip('"'))

            if not isinstance(value, six.integer_types):
                raise_invalid(self.request, **error_details)

            if param == "_since":
                operator = COMPARISON.GT
            else:
                if param == "_to":
                    message = "_to is now deprecated, you should use _before instead"
                    url = (
                        "http://cliquet.rtfd.org/en/2.4.0/api/resource"
                        ".html#list-of-available-url-parameters"
                    )
                    send_alert(self.request, message, url)
                operator = COMPARISON.LT
            filters.append(Filter(self.model.modified_field, value, operator))
            continue

        m = re.match(r"^(min|max|not|lt|gt|in|exclude)_(\w+)$", param)
        if m:
            keyword, field = m.groups()
            operator = getattr(COMPARISON, keyword.upper())
        else:
            operator, field = COMPARISON.EQ, param

        if not self.is_known_field(field):
            error_msg = "Unknown filter field '{0}'".format(param)
            error_details["description"] = error_msg
            raise_invalid(self.request, **error_details)

        value = native_value(paramvalue)
        if operator in (COMPARISON.IN, COMPARISON.EXCLUDE):
            value = set([native_value(v) for v in paramvalue.split(",")])

            all_integers = all([isinstance(v, six.integer_types) for v in value])
            all_strings = all([isinstance(v, six.text_type) for v in value])
            has_invalid_value = (field == self.model.id_field and not all_strings) or (
                field == self.model.modified_field and not all_integers
            )
            if has_invalid_value:
                raise_invalid(self.request, **error_details)

        filters.append(Filter(field, value, operator))

    return filters