diff --git a/posthog/hogql_queries/actors_query_runner.py b/posthog/hogql_queries/actors_query_runner.py index 8b750196b8a98..4e825694d919f 100644 --- a/posthog/hogql_queries/actors_query_runner.py +++ b/posthog/hogql_queries/actors_query_runner.py @@ -333,6 +333,7 @@ def to_query(self) -> ast.SelectQuery: and isinstance(self.query.source, InsightActorsQuery) and isinstance(self.query.source.source, TrendsQuery) and source_distinct_id_column is not None + and all(getattr(field, "chain", None) != ["event_distinct_ids"] for field in select_query.select) ): select_query.select.append(ast.Field(chain=[source_distinct_id_column])) diff --git a/posthog/hogql_queries/insights/trends/test/__snapshots__/test_trends.ambr b/posthog/hogql_queries/insights/trends/test/__snapshots__/test_trends.ambr index cec3b18a3ff10..2a216d55bf026 100644 --- a/posthog/hogql_queries/insights/trends/test/__snapshots__/test_trends.ambr +++ b/posthog/hogql_queries/insights/trends/test/__snapshots__/test_trends.ambr @@ -241,7 +241,6 @@ persons.created_at AS created_at, source.event_count AS event_count, source.matching_events AS matching_events, - source.event_distinct_ids, source.event_distinct_ids AS event_distinct_ids FROM (SELECT actor_id AS actor_id, @@ -1553,7 +1552,6 @@ persons.created_at AS created_at, source.event_count AS event_count, source.matching_events AS matching_events, - source.event_distinct_ids, source.event_distinct_ids AS event_distinct_ids FROM (SELECT actor_id AS actor_id, diff --git a/posthog/tasks/exports/test/test_csv_exporter.py b/posthog/tasks/exports/test/test_csv_exporter.py index 4d53742ed65bb..8d3cf5f182f27 100644 --- a/posthog/tasks/exports/test/test_csv_exporter.py +++ b/posthog/tasks/exports/test/test_csv_exporter.py @@ -4,6 +4,7 @@ from unittest.mock import MagicMock, Mock, patch, ANY from dateutil.relativedelta import relativedelta +from freezegun import freeze_time from openpyxl import load_workbook from io import BytesIO import pytest @@ -817,3 +818,71 @@ def test_csv_exporter_trends_query_with_compare_previous_option( ] self.assertEqual(lines, expected_lines) + + def test_csv_exporter_trends_actors( + self, + ) -> None: + with freeze_time("2022-06-01T12:00:00.000Z"): + _create_person(distinct_ids=[f"user_1"], team=self.team, uuid="4beb316f-23aa-2584-66d3-4a1b8ab458f2") + + events_by_person = { + "user_1": [ + { + "event": "$pageview", + "timestamp": datetime(2020, 3, 22, 13, 46), + }, + { + "event": "$pageview", + "timestamp": datetime(2020, 3, 22, 13, 47), + }, + ], + } + journeys_for(events_by_person, self.team) + _create_event( + event="$pageview", + distinct_id="user_2", # personless user + person_id="d0780d6b-ccd0-44fa-a227-47efe4f3f30d", + timestamp=datetime(2020, 3, 22, 13, 48), + team=self.team, + ) + flush_persons_and_events() + + exported_asset = ExportedAsset( + team=self.team, + export_format=ExportedAsset.ExportFormat.CSV, + export_context={ + "source": { + "kind": "ActorsQuery", + "search": "", + "select": ["actor", "event_count"], + "source": { + "day": "2020-03-22T00:00:00Z", + "kind": "InsightActorsQuery", + "series": 0, + "source": { + "kind": "TrendsQuery", + "series": [ + {"kind": "EventsNode", "math": "total", "name": "$pageview", "event": "$pageview"} + ], + "trendsFilter": {}, + }, + "includeRecordings": False, + }, + "orderBy": ["event_count DESC, actor_id DESC"], + } + }, + ) + exported_asset.save() + + with self.settings(OBJECT_STORAGE_ENABLED=True, OBJECT_STORAGE_EXPORTS_FOLDER="Test-Exports"): + csv_exporter.export_tabular(exported_asset) + content = object_storage.read(exported_asset.content_location) # type: ignore + lines = (content or "").strip().split("\r\n") + self.assertEqual( + lines, + [ + "actor.id,actor.is_identified,actor.created_at,actor.distinct_ids.0,event_count,event_distinct_ids.0", + "4beb316f-23aa-2584-66d3-4a1b8ab458f2,False,2022-06-01 12:00:00+00:00,user_1,2,user_1", + "d0780d6b-ccd0-44fa-a227-47efe4f3f30d,,,user_2,1,user_2", + ], + )