0
0
mirror of https://github.com/PostHog/posthog.git synced 2024-12-01 12:21:02 +01:00
posthog/ee/clickhouse/views/element.py
Eric Duong df583d528b
6331 pie chart persons bug (#6642)
* backend fixes and test

* add breakdown value to pie chart

* adjust test

* fix faulty test

* fill param

* fix formula tests

* more date passing

* more cleanup

* all tests working

* make test data explicit and add better checks

* support both ee and postgres

* length checks
2021-10-26 14:53:34 -04:00

65 lines
2.6 KiB
Python

from rest_framework import authentication, request, response, serializers, viewsets
from rest_framework.decorators import action
from ee.clickhouse.client import sync_execute
from ee.clickhouse.models.element import chain_to_elements
from ee.clickhouse.models.property import parse_prop_clauses
from ee.clickhouse.queries.util import parse_timestamps
from ee.clickhouse.sql.element import GET_ELEMENTS, GET_VALUES
from posthog.api.element import ElementSerializer, ElementViewSet
from posthog.models.filters import Filter
class ClickhouseElementViewSet(ElementViewSet):
@action(methods=["GET"], detail=False)
def stats(self, request: request.Request, **kwargs) -> response.Response: # type: ignore
filter = Filter(request=request, team=self.team)
date_from, date_to, date_params = parse_timestamps(filter, team_id=self.team.pk)
prop_filters, prop_filter_params = parse_prop_clauses(filter.properties, self.team.pk)
result = sync_execute(
GET_ELEMENTS.format(date_from=date_from, date_to=date_to, query=prop_filters),
{"team_id": self.team.pk, **prop_filter_params, **date_params},
)
return response.Response(
[
{
"count": elements[1],
"hash": None,
"elements": [ElementSerializer(element).data for element in chain_to_elements(elements[0])],
}
for elements in result
]
)
@action(methods=["GET"], detail=False)
def values(self, request: request.Request, **kwargs) -> response.Response: # type: ignore
key = request.GET.get("key")
value = request.GET.get("value")
select_regex = '[:|"]{}="(.*?)"'.format(key)
# Make sure key exists, otherwise could lead to sql injection lower down
if key not in self.serializer_class.Meta.fields:
return response.Response([])
if key == "tag_name":
select_regex = r"^([-_a-zA-Z0-9]*?)[\.|:]"
filter_regex = select_regex
if value:
filter_regex = r"^([-_a-zA-Z0-9]*?{}[-_a-zA-Z0-9]*?)[\.|:]".format(value)
else:
if value:
filter_regex = '[:|"]{}=".*?{}.*?"'.format(key, value)
else:
filter_regex = select_regex
result = sync_execute(
GET_VALUES.format(), {"team_id": self.team.id, "regex": select_regex, "filter_regex": filter_regex}
)
return response.Response([{"name": value[0]} for value in result])
class LegacyClickhouseElementViewSet(ClickhouseElementViewSet):
legacy_team_compatibility = True