Skip to content

Commit

Permalink
feat(data-warehouse): add views to insights (#23058)
Browse files Browse the repository at this point in the history
* add views to insights

* Update query snapshots

* Update UI snapshots for `chromium` (2)

* typing

* Update UI snapshots for `chromium` (1)

---------

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
EDsCODE and github-actions[bot] authored Jun 18, 2024
1 parent 542da1f commit 1ed340d
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 37 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ export const taxonomicFilterLogic = kea<taxonomicFilterLogicType>([
searchPlaceholder: 'data warehouse table name',
type: TaxonomicFilterGroupType.DataWarehouse,
logic: dataWarehouseSceneLogic,
value: 'dataWarehouseTables',
value: 'dataWarehouseTablesAndViews',
getName: (table: DatabaseSchemaTable) => table.name,
getValue: (table: DatabaseSchemaTable) => table.name,
getPopoverHeader: () => 'Data Warehouse Table',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,12 @@ export const dataWarehouseSceneLogic = kea<dataWarehouseSceneLogicType>([
}, {})
},
],
dataWarehouseTablesAndViews: [
(s) => [s.dataWarehouseTables, s.views],
(dataWarehouseTables, views): DatabaseSchemaTable[] => {
return [...dataWarehouseTables, ...views]
},
],
}),
listeners(({ actions, values }) => ({
deleteDataWarehouseSavedQuery: async (tableId) => {
Expand Down
91 changes: 55 additions & 36 deletions posthog/hogql/database/database.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import dataclasses
from typing import TYPE_CHECKING, Any, ClassVar, Optional, TypeAlias, cast
from collections.abc import Callable
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
from pydantic import ConfigDict, BaseModel
from sentry_sdk import capture_exception
Expand Down Expand Up @@ -247,51 +248,69 @@ def create_hogql_database(
for table in DataWarehouseTable.objects.filter(team_id=team.pk).exclude(deleted=True):
warehouse_tables[table.name] = table.hogql_definition(modifiers)

for saved_query in DataWarehouseSavedQuery.objects.filter(team_id=team.pk).exclude(deleted=True):
views[saved_query.name] = saved_query.hogql_definition()

def define_mappings(warehouse: dict[str, Table], get_table: Callable):
if "id" not in warehouse[warehouse_modifier.table_name].fields.keys():
warehouse[warehouse_modifier.table_name].fields["id"] = ExpressionField(
name="id",
expr=parse_expr(warehouse_modifier.id_field),
)

if "timestamp" not in warehouse[warehouse_modifier.table_name].fields.keys():
table_model = get_table(team=team, warehouse_modifier=warehouse_modifier)
timestamp_field_type = table_model.get_clickhouse_column_type(warehouse_modifier.timestamp_field)

# If field type is none or datetime, we can use the field directly
if timestamp_field_type is None or timestamp_field_type.startswith("DateTime"):
warehouse[warehouse_modifier.table_name].fields["timestamp"] = ExpressionField(
name="timestamp",
expr=ast.Field(chain=[warehouse_modifier.timestamp_field]),
)
else:
warehouse[warehouse_modifier.table_name].fields["timestamp"] = ExpressionField(
name="timestamp",
expr=ast.Call(name="toDateTime", args=[ast.Field(chain=[warehouse_modifier.timestamp_field])]),
)

# TODO: Need to decide how the distinct_id and person_id fields are going to be handled
if "distinct_id" not in warehouse[warehouse_modifier.table_name].fields.keys():
warehouse[warehouse_modifier.table_name].fields["distinct_id"] = ExpressionField(
name="distinct_id",
expr=parse_expr(warehouse_modifier.distinct_id_field),
)

if "person_id" not in warehouse[warehouse_modifier.table_name].fields.keys():
warehouse[warehouse_modifier.table_name].fields["person_id"] = ExpressionField(
name="person_id",
expr=parse_expr(warehouse_modifier.distinct_id_field),
)

return warehouse

if modifiers.dataWarehouseEventsModifiers:
for warehouse_modifier in modifiers.dataWarehouseEventsModifiers:
# TODO: add all field mappings
if "id" not in warehouse_tables[warehouse_modifier.table_name].fields.keys():
warehouse_tables[warehouse_modifier.table_name].fields["id"] = ExpressionField(
name="id",
expr=parse_expr(warehouse_modifier.id_field),
)

if "timestamp" not in warehouse_tables[warehouse_modifier.table_name].fields.keys():
table_model = DataWarehouseTable.objects.filter(
team_id=team.pk, name=warehouse_modifier.table_name
).latest("created_at")
timestamp_field_type = table_model.get_clickhouse_column_type(warehouse_modifier.timestamp_field)

# If field type is none or datetime, we can use the field directly
if timestamp_field_type is None or timestamp_field_type.startswith("DateTime"):
warehouse_tables[warehouse_modifier.table_name].fields["timestamp"] = ExpressionField(
name="timestamp",
expr=ast.Field(chain=[warehouse_modifier.timestamp_field]),
)
else:
warehouse_tables[warehouse_modifier.table_name].fields["timestamp"] = ExpressionField(
name="timestamp",
expr=ast.Call(name="toDateTime", args=[ast.Field(chain=[warehouse_modifier.timestamp_field])]),
)
is_view = warehouse_modifier.table_name in views.keys()

# TODO: Need to decide how the distinct_id and person_id fields are going to be handled
if "distinct_id" not in warehouse_tables[warehouse_modifier.table_name].fields.keys():
warehouse_tables[warehouse_modifier.table_name].fields["distinct_id"] = ExpressionField(
name="distinct_id",
expr=parse_expr(warehouse_modifier.distinct_id_field),
if is_view:
views = define_mappings(
views,
lambda team, warehouse_modifier: DataWarehouseSavedQuery.objects.filter(
team_id=team.pk, name=warehouse_modifier.table_name
).latest("created_at"),
)

if "person_id" not in warehouse_tables[warehouse_modifier.table_name].fields.keys():
warehouse_tables[warehouse_modifier.table_name].fields["person_id"] = ExpressionField(
name="person_id",
expr=parse_expr(warehouse_modifier.distinct_id_field),
else:
warehouse_tables = define_mappings(
warehouse_tables,
lambda team, warehouse_modifier: DataWarehouseTable.objects.filter(
team_id=team.pk, name=warehouse_modifier.table_name
).latest("created_at"),
)

database.add_warehouse_tables(**warehouse_tables)

for saved_query in DataWarehouseSavedQuery.objects.filter(team_id=team.pk).exclude(deleted=True):
views[saved_query.name] = saved_query.hogql_definition()

database.add_views(**views)

for join in DataWarehouseJoin.objects.filter(team_id=team.pk).exclude(deleted=True):
Expand Down

0 comments on commit 1ed340d

Please sign in to comment.