gooddata-fdw 1.74.1.dev1__tar.gz → 1.74.1.dev2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- gooddata_fdw-1.74.1.dev2/AGENTS.md +104 -0
- gooddata_fdw-1.74.1.dev2/CLAUDE.md +1 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/PKG-INFO +3 -3
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/docs/requirements.txt +1 -1
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/pyproject.toml +7 -7
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/.gitignore +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/.readthedocs.yaml +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/Dockerfile +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/LICENSE.txt +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/MANIFEST.in +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/Makefile +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/README.md +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/docs/_static/empty_file +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/docs/_templates/class-template.rst +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/docs/_templates/module-template.rst +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/docs/api.rst +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/docs/conf.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/docs/connecting_to_postgresql.rst +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/docs/foreign_tables.rst +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/docs/index.rst +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/docs/installation.rst +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/rebuild.sh +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/sql/create_extensions.sql +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/sql/import_gooddata.sql +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/src/gooddata_fdw/__init__.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/src/gooddata_fdw/_version.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/src/gooddata_fdw/column_utils.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/src/gooddata_fdw/column_validation.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/src/gooddata_fdw/environment.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/src/gooddata_fdw/executor.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/src/gooddata_fdw/fdw.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/src/gooddata_fdw/filter.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/src/gooddata_fdw/import_workspace.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/src/gooddata_fdw/naming.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/src/gooddata_fdw/options.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/src/gooddata_fdw/pg_logging.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/src/gooddata_fdw/result_reader.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/tests/__init__.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/tests/conftest.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/tests/execute/__init__.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/tests/execute/fixtures/execute_compute_table_all_columns.yaml +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/tests/execute/fixtures/execute_compute_table_metrics_only.yaml +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/tests/execute/fixtures/execute_compute_table_with_reduced_granularity.yaml +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/tests/execute/fixtures/execute_insight_all_columns.yaml +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/tests/execute/fixtures/execute_insight_some_columns.yaml +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/tests/execute/test_execute_compute_table.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/tests/execute/test_execute_insight.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/tests/gd_test_config.yaml +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/tests/import_foreign_schema/__init__.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/tests/import_foreign_schema/fixtures/import_compute_without_restrictions.yaml +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/tests/import_foreign_schema/fixtures/import_insights_without_restrictions.yaml +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/tests/import_foreign_schema/test_import_compute.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/tests/import_foreign_schema/test_import_insights.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/tests/overview.md +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/tests/unit_test/test_column_validation.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/tests/unit_test/test_executor.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/tests/unit_test/test_filter.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/tests/unit_test/test_options.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/tests/unit_test/test_result_reader.py +0 -0
- {gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/tox.ini +0 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# gooddata-fdw
|
|
2
|
+
|
|
3
|
+
A PostgreSQL Foreign Data Wrapper that exposes GoodData insights and semantic-model
|
|
4
|
+
computations as ordinary SQL tables. It is a Python class loaded by the multicorn
|
|
5
|
+
extension, not a compiled Postgres extension of its own: a user registers a foreign server
|
|
6
|
+
pointing at `gooddata_fdw.GoodDataForeignDataWrapper`, then either imports a foreign schema
|
|
7
|
+
(auto-generating one table per insight plus a `compute` pseudo-table) or hand-writes
|
|
8
|
+
`CREATE FOREIGN TABLE` statements. Every `SELECT` against these tables is a live API call
|
|
9
|
+
to GoodData, not a local table scan.
|
|
10
|
+
|
|
11
|
+
## Owns
|
|
12
|
+
|
|
13
|
+
- The FDW implementation that surfaces GoodData data as PostgreSQL foreign tables
|
|
14
|
+
- `IMPORT FOREIGN SCHEMA` support and the bundled SQL helper procedure
|
|
15
|
+
- The translation layer from a SQL query into an SDK execution
|
|
16
|
+
- Column-type mapping between GoodData types and PostgreSQL types
|
|
17
|
+
|
|
18
|
+
## Does NOT Own
|
|
19
|
+
|
|
20
|
+
- Core API and service client behavior → `gooddata-sdk`
|
|
21
|
+
- Flight RPC server infrastructure → `gooddata-flight-server`
|
|
22
|
+
- FlexConnect function runtime → `gooddata-flexconnect`
|
|
23
|
+
|
|
24
|
+
## Architecture
|
|
25
|
+
|
|
26
|
+
**Depends on**: `gooddata-sdk`, and at runtime a multicorn/PostgreSQL environment —
|
|
27
|
+
multicorn 1.4.0 with PostgreSQL 12 is what the package is tested against. Note that
|
|
28
|
+
multicorn is deliberately *not* a pip dependency; it is an OS-level Postgres extension.
|
|
29
|
+
|
|
30
|
+
| Module | Role |
|
|
31
|
+
|---|---|
|
|
32
|
+
| `fdw.py` | `GoodDataForeignDataWrapper` — `import_schema()` and `execute()` |
|
|
33
|
+
| `executor.py` | per-table-type execution strategies |
|
|
34
|
+
| `import_workspace.py` | foreign-table generation during import |
|
|
35
|
+
| `column_utils.py`, `column_validation.py`, `naming.py` | type mapping, validation, naming |
|
|
36
|
+
| `options.py` | server/table option parsing |
|
|
37
|
+
| `environment.py` | multicorn imports, with test stubs |
|
|
38
|
+
| `sql/` | `create_extensions.sql`, `import_gooddata.sql` |
|
|
39
|
+
|
|
40
|
+
### Setup, in PostgreSQL
|
|
41
|
+
|
|
42
|
+
```sql
|
|
43
|
+
CREATE EXTENSION multicorn;
|
|
44
|
+
CREATE EXTENSION foreign_table_exposer;
|
|
45
|
+
|
|
46
|
+
CREATE SERVER gooddata FOREIGN DATA WRAPPER multicorn
|
|
47
|
+
OPTIONS (wrapper 'gooddata_fdw.GoodDataForeignDataWrapper',
|
|
48
|
+
host 'https://example.gooddata.com', token '...');
|
|
49
|
+
|
|
50
|
+
CALL import_gooddata('my_workspace', 'all'); -- wraps IMPORT FOREIGN SCHEMA
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Two table shapes
|
|
54
|
+
|
|
55
|
+
`object_type` is `insights`, `compute` or `all`, and the choice determines which executor
|
|
56
|
+
runs at query time:
|
|
57
|
+
|
|
58
|
+
- **`insights`** — one foreign table per insight in the workspace. Queries run through the
|
|
59
|
+
insight, equivalent to `for_visualization`.
|
|
60
|
+
- **`compute`** — a single non-relational `compute` pseudo-table mapping every metric, fact
|
|
61
|
+
and label in the workspace catalog. Queries select arbitrary combinations and are
|
|
62
|
+
translated into `Attribute`/`Metric` objects and executed via `sdk.tables.for_items`.
|
|
63
|
+
|
|
64
|
+
This distinction is the single most important architectural fact here for anyone touching
|
|
65
|
+
import or execution code.
|
|
66
|
+
|
|
67
|
+
## Gotchas
|
|
68
|
+
|
|
69
|
+
**Filter pushdown is limited, and the limits are known rather than bugs.** Only simple
|
|
70
|
+
attribute `IN` filters and single-day-granularity date ranges push down. `OR` never pushes
|
|
71
|
+
down. Pushdown works for `compute` and hand-written tables but not for `insights`-imported
|
|
72
|
+
tables. And against `compute`, a column used in `WHERE` but absent from `SELECT` fails
|
|
73
|
+
outright, due to a multicorn limitation. There are `# TODO: push down more filters` markers
|
|
74
|
+
in `executor.py` — treat these as documented boundaries before "fixing" them.
|
|
75
|
+
|
|
76
|
+
**multicorn is stubbed under pytest.** `environment.py` imports the real multicorn only
|
|
77
|
+
when neither `pytest` nor `sphinx` is in `sys.modules`, substituting stub classes for
|
|
78
|
+
`ForeignDataWrapper`, `ColumnDefinition`, `Qual` and `TableDefinition` otherwise. That is
|
|
79
|
+
why the unit tests run with no Postgres present, why the multicorn dependency is commented
|
|
80
|
+
out in `pyproject.toml`, and why `ty` has `allowed-unresolved-imports = ["multicorn"]`.
|
|
81
|
+
Do not try to `pip install multicorn`, and do not assume stub behavior generalizes to the
|
|
82
|
+
real runtime.
|
|
83
|
+
|
|
84
|
+
**This is a read-only FDW.** `rowid_column`, `insert`, `update` and `delete` are no-op
|
|
85
|
+
passthroughs to the multicorn base class. There is no partial write support to build on.
|
|
86
|
+
|
|
87
|
+
**Numeric precision comes from import options, not code.** Metric and fact columns become
|
|
88
|
+
`DECIMAL` sized from the metric's display format or the `numeric_max_size` import option;
|
|
89
|
+
attribute and label types are derived through the SDK's converter store. A precision
|
|
90
|
+
mismatch is usually an import-option problem.
|
|
91
|
+
|
|
92
|
+
**Low-churn package.** Substantive source changes are infrequent — most recent commits are
|
|
93
|
+
release and tooling automation. Nothing in the repo marks it deprecated, and it is
|
|
94
|
+
classified Production/Stable, but do not assume recent behavior verification.
|
|
95
|
+
|
|
96
|
+
## Testing
|
|
97
|
+
|
|
98
|
+
Package-local pytest suites under `tests/`, with cassettes in `tests/execute/fixtures/`.
|
|
99
|
+
|
|
100
|
+
The FDW tests need a service the default stack does not start:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
docker compose --profile fdw up -d # PostgreSQL + gooddata-fdw extension on port 2543
|
|
104
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@AGENTS.md
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: gooddata-fdw
|
|
3
|
-
Version: 1.74.1.
|
|
3
|
+
Version: 1.74.1.dev2
|
|
4
4
|
Summary: GoodData Cloud Foreign Data Wrapper For PostgreSQL
|
|
5
|
-
Project-URL: Documentation, https://gooddata-fdw.readthedocs.io/en/v1.74.1.
|
|
5
|
+
Project-URL: Documentation, https://gooddata-fdw.readthedocs.io/en/v1.74.1.dev2
|
|
6
6
|
Project-URL: Source, https://github.com/gooddata/gooddata-python-sdk
|
|
7
7
|
Author-email: GoodData <support@gooddata.com>
|
|
8
8
|
License-Expression: MIT
|
|
@@ -20,7 +20,7 @@ Classifier: Topic :: Scientific/Engineering
|
|
|
20
20
|
Classifier: Topic :: Software Development
|
|
21
21
|
Classifier: Typing :: Typed
|
|
22
22
|
Requires-Python: >=3.10
|
|
23
|
-
Requires-Dist: gooddata-sdk~=1.74.1.
|
|
23
|
+
Requires-Dist: gooddata-sdk~=1.74.1.dev2
|
|
24
24
|
Description-Content-Type: text/markdown
|
|
25
25
|
|
|
26
26
|
# GoodData Foreign Data Wrapper
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# (C) 2025 GoodData Corporation
|
|
2
2
|
[project]
|
|
3
3
|
name = "gooddata-fdw"
|
|
4
|
-
version = "1.74.1.
|
|
4
|
+
version = "1.74.1.dev2"
|
|
5
5
|
description = "GoodData Cloud Foreign Data Wrapper For PostgreSQL"
|
|
6
6
|
readme = "README.md"
|
|
7
7
|
license = "MIT"
|
|
@@ -26,7 +26,7 @@ keywords = [
|
|
|
26
26
|
]
|
|
27
27
|
requires-python = ">=3.10"
|
|
28
28
|
dependencies = [
|
|
29
|
-
"gooddata-sdk~=1.74.1.
|
|
29
|
+
"gooddata-sdk~=1.74.1.dev2",
|
|
30
30
|
# "multicorn>=1.4.0", # Uncommented as it was in original setup.py
|
|
31
31
|
]
|
|
32
32
|
classifiers = [
|
|
@@ -44,17 +44,17 @@ classifiers = [
|
|
|
44
44
|
]
|
|
45
45
|
|
|
46
46
|
[project.urls]
|
|
47
|
-
Documentation = "https://gooddata-fdw.readthedocs.io/en/v1.74.1.
|
|
47
|
+
Documentation = "https://gooddata-fdw.readthedocs.io/en/v1.74.1.dev2"
|
|
48
48
|
Source = "https://github.com/gooddata/gooddata-python-sdk"
|
|
49
49
|
|
|
50
50
|
[dependency-groups]
|
|
51
51
|
test = [
|
|
52
|
-
"pytest~=
|
|
53
|
-
"pytest-cov~=
|
|
52
|
+
"pytest~=9.1.1",
|
|
53
|
+
"pytest-cov~=7.1.0",
|
|
54
54
|
"pytest-json-report==1.5.0",
|
|
55
|
-
"vcrpy~=8.
|
|
55
|
+
"vcrpy~=8.3.0",
|
|
56
56
|
# TODO - Bump the version together with bumping the version of openapi generator
|
|
57
|
-
"urllib3~=2.
|
|
57
|
+
"urllib3~=2.7.0",
|
|
58
58
|
"pyyaml",
|
|
59
59
|
"tests_support",
|
|
60
60
|
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/tests/execute/test_execute_compute_table.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/tests/import_foreign_schema/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gooddata_fdw-1.74.1.dev1 → gooddata_fdw-1.74.1.dev2}/tests/unit_test/test_column_validation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|