castor-extractor 0.25.6__py3-none-any.whl → 0.25.9__py3-none-any.whl
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.
Potentially problematic release.
This version of castor-extractor might be problematic. Click here for more details.
- CHANGELOG.md +14 -0
- castor_extractor/commands/extract_sqlserver.py +0 -2
- castor_extractor/exceptions.py +5 -0
- castor_extractor/utils/client/abstract.py +0 -11
- castor_extractor/utils/client/query.py +16 -2
- castor_extractor/visualization/count/assets.py +2 -0
- castor_extractor/visualization/count/client/client.py +6 -2
- castor_extractor/visualization/count/client/queries/canvas_loads.sql +14 -0
- castor_extractor/visualization/count/client/queries/queries.sql +23 -0
- castor_extractor/visualization/sigma/client/client.py +4 -0
- castor_extractor/warehouse/abstract/extract.py +2 -3
- castor_extractor/warehouse/abstract/query.py +1 -19
- castor_extractor/warehouse/bigquery/extract.py +7 -0
- castor_extractor/warehouse/databricks/extract.py +7 -0
- castor_extractor/warehouse/snowflake/extract.py +18 -0
- castor_extractor/warehouse/sqlserver/client.py +20 -14
- castor_extractor/warehouse/sqlserver/extract.py +0 -2
- {castor_extractor-0.25.6.dist-info → castor_extractor-0.25.9.dist-info}/METADATA +15 -1
- {castor_extractor-0.25.6.dist-info → castor_extractor-0.25.9.dist-info}/RECORD +22 -19
- {castor_extractor-0.25.6.dist-info → castor_extractor-0.25.9.dist-info}/LICENCE +0 -0
- {castor_extractor-0.25.6.dist-info → castor_extractor-0.25.9.dist-info}/WHEEL +0 -0
- {castor_extractor-0.25.6.dist-info → castor_extractor-0.25.9.dist-info}/entry_points.txt +0 -0
CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.25.9 - 2025-10-09
|
|
4
|
+
|
|
5
|
+
* Snowflake: raise an exception when no database is available for extraction
|
|
6
|
+
* Databricks: raise an exception when no database is available for extraction
|
|
7
|
+
* BigQuery: raise an exception when no project is available for extraction
|
|
8
|
+
|
|
9
|
+
## 0.25.8 - 2025-10-09
|
|
10
|
+
|
|
11
|
+
* Count: extracting queries and canvas_loads
|
|
12
|
+
|
|
13
|
+
## 0.25.7 - 2025-10-07
|
|
14
|
+
|
|
15
|
+
* SqlServer: Ensure database consistency between query and engine
|
|
16
|
+
|
|
3
17
|
## 0.25.6 - 2025-10-06
|
|
4
18
|
|
|
5
19
|
* PowerBi: Support additional authentication methods
|
|
@@ -11,7 +11,6 @@ def main():
|
|
|
11
11
|
|
|
12
12
|
parser.add_argument("-H", "--host", help="MSSQL Host")
|
|
13
13
|
parser.add_argument("-P", "--port", help="MSSQL Port")
|
|
14
|
-
parser.add_argument("-d", "--database", help="MSSQL Database")
|
|
15
14
|
parser.add_argument("-u", "--user", help="MSSQL User")
|
|
16
15
|
parser.add_argument("-p", "--password", help="MSSQL Password")
|
|
17
16
|
|
|
@@ -47,7 +46,6 @@ def main():
|
|
|
47
46
|
|
|
48
47
|
sqlserver.extract_all(
|
|
49
48
|
host=args.host,
|
|
50
|
-
database=args.database,
|
|
51
49
|
port=args.port,
|
|
52
50
|
user=args.user,
|
|
53
51
|
password=args.password,
|
|
@@ -26,17 +26,6 @@ class AbstractSourceClient(ABC):
|
|
|
26
26
|
def execute(self, query: ExtractionQuery) -> Iterator[dict]:
|
|
27
27
|
pass
|
|
28
28
|
|
|
29
|
-
def set_database(self, database: Optional[str]) -> None:
|
|
30
|
-
"""
|
|
31
|
-
Set the active database for this client.
|
|
32
|
-
|
|
33
|
-
Some source technologies require establishing a new connection
|
|
34
|
-
or using a different connection URI when switching databases.
|
|
35
|
-
|
|
36
|
-
Default behaviour is to do nothing.
|
|
37
|
-
"""
|
|
38
|
-
pass
|
|
39
|
-
|
|
40
29
|
|
|
41
30
|
class SqlalchemyClient(AbstractSourceClient, ABC):
|
|
42
31
|
def __init__(self, credentials: dict):
|
|
@@ -1,6 +1,20 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
|
|
1
4
|
class ExtractionQuery:
|
|
2
|
-
"""
|
|
5
|
+
"""
|
|
6
|
+
Contains useful context to run the query:
|
|
7
|
+
- the sql statement itself
|
|
8
|
+
- parameters { ... }
|
|
9
|
+
- optionally, the target database (can be used to change the engine's URI)
|
|
10
|
+
"""
|
|
3
11
|
|
|
4
|
-
def __init__(
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
statement: str,
|
|
15
|
+
params: dict,
|
|
16
|
+
database: Optional[str] = None,
|
|
17
|
+
):
|
|
5
18
|
self.statement = statement
|
|
6
19
|
self.params = params
|
|
20
|
+
self.database = database
|
|
@@ -3,6 +3,7 @@ from dataclasses import asdict
|
|
|
3
3
|
from typing import Any, Iterator
|
|
4
4
|
|
|
5
5
|
from ....utils import load_file
|
|
6
|
+
from ....warehouse.abstract import TimeFilter
|
|
6
7
|
from ....warehouse.bigquery import BigQueryClient
|
|
7
8
|
from ..assets import (
|
|
8
9
|
CountAsset,
|
|
@@ -27,18 +28,21 @@ class CountClient(BigQueryClient):
|
|
|
27
28
|
super().__init__(asdict(credentials))
|
|
28
29
|
self.project_id = credentials.project_id
|
|
29
30
|
self.dataset_id = credentials.dataset_id
|
|
31
|
+
self.time_filter = TimeFilter.default() # setting current date - 1
|
|
30
32
|
|
|
31
33
|
def _load_query(self, asset: CountAsset) -> str:
|
|
32
34
|
query = load_file(
|
|
33
35
|
f"{_QUERIES_FOLDER}/{asset.name.lower()}.sql", __file__
|
|
34
36
|
)
|
|
35
37
|
return query.format(
|
|
36
|
-
project_id=self.project_id,
|
|
38
|
+
project_id=self.project_id,
|
|
39
|
+
dataset_id=self.dataset_id,
|
|
40
|
+
extract_date=self.time_filter.day,
|
|
37
41
|
)
|
|
38
42
|
|
|
39
43
|
def fetch(self, asset: CountAsset) -> Iterator[dict[str, Any]]:
|
|
40
44
|
"""
|
|
41
|
-
Fetch the asset given as param
|
|
45
|
+
Fetch the asset given as a param by running a BigQuery query.
|
|
42
46
|
"""
|
|
43
47
|
logger.info(f"Running BigQuery query to fetch: {asset.name}")
|
|
44
48
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
WITH view_count AS(
|
|
2
|
+
SELECT
|
|
3
|
+
canvas_key,
|
|
4
|
+
DATE(loaded_at) AS load_day
|
|
5
|
+
FROM `{project_id}.{dataset_id}.canvas_loads`
|
|
6
|
+
WHERE TRUE
|
|
7
|
+
AND date(loaded_at) = '{extract_date}'
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
SELECT
|
|
11
|
+
canvas_key,
|
|
12
|
+
COUNT(*) AS view_count
|
|
13
|
+
FROM view_count
|
|
14
|
+
GROUP BY canvas_key
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
WITH ranked_queries AS (
|
|
2
|
+
SELECT
|
|
3
|
+
cell_key,
|
|
4
|
+
connection_key,
|
|
5
|
+
query,
|
|
6
|
+
started_at,
|
|
7
|
+
ROW_NUMBER() OVER (
|
|
8
|
+
PARTITION BY cell_key
|
|
9
|
+
ORDER BY started_at DESC
|
|
10
|
+
) AS rank
|
|
11
|
+
FROM `{project_id}.{dataset_id}.queries`
|
|
12
|
+
WHERE TRUE
|
|
13
|
+
AND DATE(started_at) = '{extract_date}'
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
SELECT
|
|
17
|
+
cell_key,
|
|
18
|
+
connection_key,
|
|
19
|
+
query,
|
|
20
|
+
started_at
|
|
21
|
+
FROM ranked_queries
|
|
22
|
+
WHERE TRUE
|
|
23
|
+
AND rank = 1
|
|
@@ -48,10 +48,9 @@ class SQLExtractionProcessor:
|
|
|
48
48
|
# dict > set > dict
|
|
49
49
|
return [dict(t) for t in {tuple(d.items()) for d in data}]
|
|
50
50
|
|
|
51
|
-
def
|
|
51
|
+
def fetch(self, query: ExtractionQuery) -> Iterator[dict]:
|
|
52
52
|
default: Callable[[], Iterator] = lambda: iter(()) # type: ignore
|
|
53
53
|
decorator = safe_mode(self._safe_mode, default)
|
|
54
|
-
self._client.set_database(query.database)
|
|
55
54
|
decorated_execute = decorator(self._client.execute)
|
|
56
55
|
return decorated_execute(query)
|
|
57
56
|
|
|
@@ -63,7 +62,7 @@ class SQLExtractionProcessor:
|
|
|
63
62
|
for i, query in enumerate(queries):
|
|
64
63
|
logger.info(f"Extracting {asset.value}: query {i + 1}/{total}")
|
|
65
64
|
# concatenate results of all queries
|
|
66
|
-
data = chain(data, self.
|
|
65
|
+
data = chain(data, self.fetch(query))
|
|
67
66
|
|
|
68
67
|
if self._query_builder.needs_deduplication(asset):
|
|
69
68
|
# cast the list to iterator, but the streaming pipeline is broken in that case
|
|
@@ -3,6 +3,7 @@ import os
|
|
|
3
3
|
from abc import ABC, abstractmethod
|
|
4
4
|
from typing import Optional
|
|
5
5
|
|
|
6
|
+
from ...utils import ExtractionQuery
|
|
6
7
|
from .asset import WarehouseAsset
|
|
7
8
|
from .time_filter import TimeFilter
|
|
8
9
|
|
|
@@ -20,25 +21,6 @@ class AssetNotSupportedError(NotImplementedError):
|
|
|
20
21
|
super().__init__(msg)
|
|
21
22
|
|
|
22
23
|
|
|
23
|
-
class ExtractionQuery:
|
|
24
|
-
"""
|
|
25
|
-
Contains useful context to run the query:
|
|
26
|
-
- the sql statement itself
|
|
27
|
-
- parameters { ... }
|
|
28
|
-
- optionally, the target database (can be used to change the engine's URI)
|
|
29
|
-
"""
|
|
30
|
-
|
|
31
|
-
def __init__(
|
|
32
|
-
self,
|
|
33
|
-
statement: str,
|
|
34
|
-
params: dict,
|
|
35
|
-
database: Optional[str] = None,
|
|
36
|
-
):
|
|
37
|
-
self.statement = statement
|
|
38
|
-
self.params = params
|
|
39
|
-
self.database = database
|
|
40
|
-
|
|
41
|
-
|
|
42
24
|
class AbstractQueryBuilder(ABC):
|
|
43
25
|
"""
|
|
44
26
|
Build queries necessary to extract warehouse assets.
|
|
@@ -2,6 +2,10 @@ import json
|
|
|
2
2
|
import logging
|
|
3
3
|
from typing import cast
|
|
4
4
|
|
|
5
|
+
from castor_extractor.exceptions import ( # type: ignore
|
|
6
|
+
NoDatabaseProvidedException,
|
|
7
|
+
)
|
|
8
|
+
|
|
5
9
|
from ...logger import add_logging_file_handler
|
|
6
10
|
from ...utils import LocalStorage, SafeMode, from_env, write_summary
|
|
7
11
|
from ..abstract import (
|
|
@@ -62,6 +66,9 @@ def extract_all(**kwargs) -> None:
|
|
|
62
66
|
db_blocked=kwargs.get("db_blocked"),
|
|
63
67
|
dataset_blocked=kwargs.get("dataset_blocked"),
|
|
64
68
|
)
|
|
69
|
+
projects = client.get_projects()
|
|
70
|
+
if not projects:
|
|
71
|
+
raise NoDatabaseProvidedException
|
|
65
72
|
|
|
66
73
|
logger.info(f"Available projects: {client.get_projects()}\n")
|
|
67
74
|
|
|
@@ -2,6 +2,10 @@ import logging
|
|
|
2
2
|
from datetime import date
|
|
3
3
|
from typing import Optional
|
|
4
4
|
|
|
5
|
+
from castor_extractor.exceptions import ( # type: ignore
|
|
6
|
+
NoDatabaseProvidedException,
|
|
7
|
+
)
|
|
8
|
+
|
|
5
9
|
from ...utils import AbstractStorage, LocalStorage, write_summary
|
|
6
10
|
from ..abstract import (
|
|
7
11
|
ADDITIONAL_LINEAGE_ASSETS,
|
|
@@ -177,6 +181,9 @@ def extract_all(**kwargs) -> None:
|
|
|
177
181
|
db_blocked=kwargs.get("db_blocked"),
|
|
178
182
|
)
|
|
179
183
|
|
|
184
|
+
if not client.databases():
|
|
185
|
+
raise NoDatabaseProvidedException
|
|
186
|
+
|
|
180
187
|
storage = LocalStorage(directory=output_directory)
|
|
181
188
|
|
|
182
189
|
extractor = DatabricksExtractionProcessor(
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
|
|
3
|
+
from castor_extractor.exceptions import ( # type: ignore
|
|
4
|
+
NoDatabaseProvidedException,
|
|
5
|
+
)
|
|
6
|
+
|
|
3
7
|
from ...utils import LocalStorage, from_env, write_summary
|
|
4
8
|
from ..abstract import (
|
|
5
9
|
CATALOG_ASSETS,
|
|
@@ -60,6 +64,14 @@ def _credentials(params: dict) -> dict:
|
|
|
60
64
|
raise ValueError("missing password or private key")
|
|
61
65
|
|
|
62
66
|
|
|
67
|
+
def _get_database_names(
|
|
68
|
+
extractor: SQLExtractionProcessor, query_builder: SnowflakeQueryBuilder
|
|
69
|
+
) -> set[str]:
|
|
70
|
+
db_query = query_builder.build(WarehouseAsset.DATABASE)
|
|
71
|
+
databases = list(extractor.fetch(db_query[0]))
|
|
72
|
+
return {db["database_name"] for db in databases}
|
|
73
|
+
|
|
74
|
+
|
|
63
75
|
def extract_all(**kwargs) -> None:
|
|
64
76
|
"""
|
|
65
77
|
Extract all assets from Snowflake and store the results in CSV files
|
|
@@ -85,6 +97,12 @@ def extract_all(**kwargs) -> None:
|
|
|
85
97
|
storage=storage,
|
|
86
98
|
)
|
|
87
99
|
|
|
100
|
+
database_names = _get_database_names(extractor, query_builder)
|
|
101
|
+
if not database_names:
|
|
102
|
+
raise NoDatabaseProvidedException
|
|
103
|
+
|
|
104
|
+
logger.info(f"Available databases: {database_names}\n")
|
|
105
|
+
|
|
88
106
|
for group in extractable_asset_groups(SNOWFLAKE_ASSETS):
|
|
89
107
|
for asset in group:
|
|
90
108
|
logger.info(f"Extracting `{asset.value.upper()}` ...")
|
|
@@ -4,7 +4,8 @@ from typing import Optional
|
|
|
4
4
|
|
|
5
5
|
from sqlalchemy import create_engine, text
|
|
6
6
|
|
|
7
|
-
from ...utils import
|
|
7
|
+
from ...utils import SqlalchemyClient, uri_encode
|
|
8
|
+
from ..abstract import ExtractionQuery
|
|
8
9
|
|
|
9
10
|
logger = logging.getLogger(__name__)
|
|
10
11
|
|
|
@@ -50,12 +51,25 @@ class MSSQLClient(SqlalchemyClient):
|
|
|
50
51
|
)
|
|
51
52
|
return uri
|
|
52
53
|
|
|
54
|
+
def _set_database(self, database: Optional[str]) -> None:
|
|
55
|
+
"""
|
|
56
|
+
To support SQL Server running on Azure, we must change the engine's
|
|
57
|
+
URI depending on the case:
|
|
58
|
+
- URI/database for database-scoped queries
|
|
59
|
+
- URI otherwise
|
|
60
|
+
https://learn.microsoft.com/en-us/sql/t-sql/language-elements/use-transact-sql?view=sql-server-2017#database_name
|
|
61
|
+
https://github.com/dbeaver/dbeaver/issues/5258
|
|
62
|
+
"""
|
|
63
|
+
database_uri = f"{self._uri}/{database}" if database else self._uri
|
|
64
|
+
self._engine = create_engine(database_uri, **self._options)
|
|
65
|
+
|
|
53
66
|
def execute(self, query: ExtractionQuery) -> Iterator[dict]:
|
|
54
67
|
"""
|
|
55
68
|
Re-implements the SQLAlchemyClient execute function to ensure we consume
|
|
56
69
|
the cursor before calling connection.close() as it wipes out the data
|
|
57
70
|
otherwise
|
|
58
71
|
"""
|
|
72
|
+
self._set_database(query.database)
|
|
59
73
|
connection = self.connect()
|
|
60
74
|
try:
|
|
61
75
|
proxy = connection.execute(text(query.statement), query.params)
|
|
@@ -64,18 +78,6 @@ class MSSQLClient(SqlalchemyClient):
|
|
|
64
78
|
finally:
|
|
65
79
|
self.close()
|
|
66
80
|
|
|
67
|
-
def set_database(self, database: Optional[str]) -> None:
|
|
68
|
-
"""
|
|
69
|
-
To support SQL Server running on Azure, we must change the engine's
|
|
70
|
-
URI for each database-scoped query
|
|
71
|
-
https://chatgpt.com/share/68de93c3-9550-8001-9d54-c5da86faa43c
|
|
72
|
-
"""
|
|
73
|
-
if not database:
|
|
74
|
-
return
|
|
75
|
-
self.close()
|
|
76
|
-
database_uri = f"{self._uri}/{database}"
|
|
77
|
-
self._engine = create_engine(database_uri, **self._options)
|
|
78
|
-
|
|
79
81
|
def get_databases(self) -> list[str]:
|
|
80
82
|
result = self.execute(
|
|
81
83
|
ExtractionQuery("SELECT name FROM sys.databases", {})
|
|
@@ -128,7 +130,11 @@ class MSSQLClient(SqlalchemyClient):
|
|
|
128
130
|
FROM
|
|
129
131
|
[{database}].sys.database_query_store_options
|
|
130
132
|
"""
|
|
131
|
-
query = ExtractionQuery(
|
|
133
|
+
query = ExtractionQuery(
|
|
134
|
+
statement=sql,
|
|
135
|
+
params={},
|
|
136
|
+
database=database,
|
|
137
|
+
)
|
|
132
138
|
# 2 = READ_WRITE, which means the Query Store is activated
|
|
133
139
|
return next(self.execute(query))["desired_state"] == 2
|
|
134
140
|
|
|
@@ -32,7 +32,6 @@ MSSQL_USER = "CASTOR_MSSQL_USER"
|
|
|
32
32
|
MSSQL_PASSWORD = "CASTOR_MSSQL_PASSWORD" # noqa: S105
|
|
33
33
|
MSSQL_HOST = "CASTOR_MSSQL_HOST"
|
|
34
34
|
MSSQL_PORT = "CASTOR_MSSQL_PORT"
|
|
35
|
-
MSSQL_DATABASE = "CASTOR_MSSQL_DATABASE"
|
|
36
35
|
|
|
37
36
|
|
|
38
37
|
def _credentials(params: dict) -> dict:
|
|
@@ -43,7 +42,6 @@ def _credentials(params: dict) -> dict:
|
|
|
43
42
|
"password": params.get("password") or from_env(MSSQL_PASSWORD),
|
|
44
43
|
"host": params.get("host") or from_env(MSSQL_HOST),
|
|
45
44
|
"port": params.get("port") or from_env(MSSQL_PORT),
|
|
46
|
-
"database": params.get("database") or from_env(MSSQL_DATABASE),
|
|
47
45
|
}
|
|
48
46
|
|
|
49
47
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: castor-extractor
|
|
3
|
-
Version: 0.25.
|
|
3
|
+
Version: 0.25.9
|
|
4
4
|
Summary: Extract your metadata assets.
|
|
5
5
|
Home-page: https://www.castordoc.com/
|
|
6
6
|
License: EULA
|
|
@@ -216,6 +216,20 @@ For any questions or bug report, contact us at [support@coalesce.io](mailto:supp
|
|
|
216
216
|
|
|
217
217
|
# Changelog
|
|
218
218
|
|
|
219
|
+
## 0.25.9 - 2025-10-09
|
|
220
|
+
|
|
221
|
+
* Snowflake: raise an exception when no database is available for extraction
|
|
222
|
+
* Databricks: raise an exception when no database is available for extraction
|
|
223
|
+
* BigQuery: raise an exception when no project is available for extraction
|
|
224
|
+
|
|
225
|
+
## 0.25.8 - 2025-10-09
|
|
226
|
+
|
|
227
|
+
* Count: extracting queries and canvas_loads
|
|
228
|
+
|
|
229
|
+
## 0.25.7 - 2025-10-07
|
|
230
|
+
|
|
231
|
+
* SqlServer: Ensure database consistency between query and engine
|
|
232
|
+
|
|
219
233
|
## 0.25.6 - 2025-10-06
|
|
220
234
|
|
|
221
235
|
* PowerBi: Support additional authentication methods
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
CHANGELOG.md,sha256=
|
|
1
|
+
CHANGELOG.md,sha256=_a0SAY_yUw6oLXAGY2GZRZmOytS5lHUVP6-6mLD1XgY,21853
|
|
2
2
|
Dockerfile,sha256=xQ05-CFfGShT3oUqaiumaldwA288dj9Yb_pxofQpufg,301
|
|
3
3
|
DockerfileUsage.md,sha256=2hkJQF-5JuuzfPZ7IOxgM6QgIQW7l-9oRMFVwyXC4gE,998
|
|
4
4
|
LICENCE,sha256=sL-IGa4hweyya1HgzMskrRdybbIa2cktzxb5qmUgDg8,8254
|
|
@@ -25,12 +25,13 @@ castor_extractor/commands/extract_salesforce.py,sha256=3j3YTmMkPAwocR-B1ozJQai0U
|
|
|
25
25
|
castor_extractor/commands/extract_salesforce_reporting.py,sha256=FdANTNiLkIPdm80XMYxWReHjdycLsIa61pyeCD-sUDk,962
|
|
26
26
|
castor_extractor/commands/extract_sigma.py,sha256=sxewHcZ1Doq35V2qnpX_zCKKXkrb1_9bYjUMg7BOW-k,643
|
|
27
27
|
castor_extractor/commands/extract_snowflake.py,sha256=GwlrRxwEBjHqGs_3bs5vM9fzmv61_iwvBr1KcIgFgWM,2161
|
|
28
|
-
castor_extractor/commands/extract_sqlserver.py,sha256=
|
|
28
|
+
castor_extractor/commands/extract_sqlserver.py,sha256=NNYfAOG-NJX0F_q0yBD-msIiwyp04Ne3fJs8hggv6YQ,1565
|
|
29
29
|
castor_extractor/commands/extract_strategy.py,sha256=Q-pUymatPrBFGXobhyUPzFph0-t774-XOpjdCFF1dYo,821
|
|
30
30
|
castor_extractor/commands/extract_tableau.py,sha256=cfH-b0Hq9LGrQSJv02Yr_4d6oNqhxwDqUcKraE-5fRc,2134
|
|
31
31
|
castor_extractor/commands/extract_thoughtspot.py,sha256=caAYJlH-vK7u5IUB6OKXxcaWfLgc7d_XqnFDWK6YNS4,639
|
|
32
32
|
castor_extractor/commands/file_check.py,sha256=TJx76Ymd0QCECmq35zRJMkPE8DJtSInB28MuSXWk8Ao,2644
|
|
33
33
|
castor_extractor/commands/upload.py,sha256=sqpEF_qqCNvT_niIrM6jPhzLaFVjtYwpc2iZw540F20,1633
|
|
34
|
+
castor_extractor/exceptions.py,sha256=WypgqL8AxYL1viYUCSY4528pk5TRcqVNPvyLMMMDWGw,238
|
|
34
35
|
castor_extractor/file_checker/__init__.py,sha256=OSt6YLhUT42U_Cp3LCLHMVruwDkksL75Ij13X2UPnVk,119
|
|
35
36
|
castor_extractor/file_checker/column.py,sha256=6bJhcW1snYwgHKkqlS0Ak7XLHZr4YBwO46JCIlnQNKg,3086
|
|
36
37
|
castor_extractor/file_checker/column_test.py,sha256=1j8PxvmvmJgpd-mk30iMYOme32ovPSIn4yCXywFoXrg,1935
|
|
@@ -102,7 +103,7 @@ castor_extractor/utils/argument_parser_test.py,sha256=wnyLFJ74iEiPxxLSbwFtckR7FI
|
|
|
102
103
|
castor_extractor/utils/batch.py,sha256=SFlLmJgVjV2nVhIrjVIEp8wJ9du4dKKHq8YVYubnwQQ,448
|
|
103
104
|
castor_extractor/utils/batch_test.py,sha256=84JYXOxiTkZFAceVh0mzN6VtKxcqoFPbxkZfIDyLGlg,606
|
|
104
105
|
castor_extractor/utils/client/__init__.py,sha256=h5gm8UNNCCkAqhjYK5f6BY7k0cHFOyAvkmlktqwpir0,392
|
|
105
|
-
castor_extractor/utils/client/abstract.py,sha256=
|
|
106
|
+
castor_extractor/utils/client/abstract.py,sha256=CWF7_afNpEZ3jor-22wXbKIvM20ukHkaDy_uknKz8B0,2075
|
|
106
107
|
castor_extractor/utils/client/api/__init__.py,sha256=vlG7WXznYgLTn3XyMGsyUkgRkup8FbKM14EXJ8mv-b0,264
|
|
107
108
|
castor_extractor/utils/client/api/auth.py,sha256=lq0K3UEl1vwIIa_vKTdlpIQPdE5K1-5DXmCwO4dKzng,1890
|
|
108
109
|
castor_extractor/utils/client/api/auth_test.py,sha256=LlyXytnatg6ZzR4Zkvzk0BH99FYhHX7qn_nyr2MSnDI,1305
|
|
@@ -115,7 +116,7 @@ castor_extractor/utils/client/api/safe_request_test.py,sha256=LqS5FBxs6lLLcTkcgx
|
|
|
115
116
|
castor_extractor/utils/client/api/utils.py,sha256=jr8CWf48cIp8QP1P7oZ1zg9WaGlDO3mqCWgQKdEcpyc,238
|
|
116
117
|
castor_extractor/utils/client/api/utils_test.py,sha256=a5aL-pCwa74C8Ne7OT169Bjp8WPDV5Fl8MxNxAllHJg,514
|
|
117
118
|
castor_extractor/utils/client/postgres.py,sha256=n6ulaT222WWPY0_6qAZ0MHF0m91HtI9mMqL71nyygo0,866
|
|
118
|
-
castor_extractor/utils/client/query.py,sha256=
|
|
119
|
+
castor_extractor/utils/client/query.py,sha256=Ucbv8dq5xRziV4HusleY2eJE3Whp8fHsVeQlPeVTuLs,473
|
|
119
120
|
castor_extractor/utils/client/uri.py,sha256=jmP9hY-6PRqdc3-vAOdtll_U6q9VCqSqmBAN6QRs3ZI,150
|
|
120
121
|
castor_extractor/utils/client/uri_test.py,sha256=1XKF6qSseCeD4G4ckaNO07JXfGbt7XUVinOZdpEYrDQ,259
|
|
121
122
|
castor_extractor/utils/collection.py,sha256=g2HmB0ievvYHWaZ8iEzkcPPkrBFsh6R6b_liBqcsMjc,3044
|
|
@@ -162,14 +163,16 @@ castor_extractor/utils/validation_test.py,sha256=A7P6VmI0kYX2aGIeEN12y7LsY7Kpm8p
|
|
|
162
163
|
castor_extractor/utils/write.py,sha256=KQVWF29N766avzmSb129IUWrId5c_8BtnYhVLmU6YIs,2133
|
|
163
164
|
castor_extractor/visualization/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
164
165
|
castor_extractor/visualization/count/__init__.py,sha256=lvxGtSe3erjTYK0aPnkOyJibcsC6Q1AFchnK-hZt558,114
|
|
165
|
-
castor_extractor/visualization/count/assets.py,sha256=
|
|
166
|
+
castor_extractor/visualization/count/assets.py,sha256=zvj2FuCrZlyKPAd8lx5rgWPKsEQ0biQJCk7AEYj6qd0,290
|
|
166
167
|
castor_extractor/visualization/count/client/__init__.py,sha256=YawYDutDI0sprp72jN9tKi8bbXCoc0Ij0Ev582tKjqk,74
|
|
167
|
-
castor_extractor/visualization/count/client/client.py,sha256=
|
|
168
|
+
castor_extractor/visualization/count/client/client.py,sha256=vSrV8V3acQAz9Hc2_DKjeU500bx2FT-DHrzUwTdjroo,1706
|
|
168
169
|
castor_extractor/visualization/count/client/credentials.py,sha256=LZWvcz7p5lrgdgoIQLcxFyv4gqUBW4Jj4qDKN-VW31I,273
|
|
170
|
+
castor_extractor/visualization/count/client/queries/canvas_loads.sql,sha256=suR5_X2SU9UIGwDi7mSxZrJvoh_-4WJwgtfBYnKMV1E,288
|
|
169
171
|
castor_extractor/visualization/count/client/queries/canvas_permissions.sql,sha256=iFmMfR0zusjxTxmYUS6p0kibZCsnHOQMbAlxaNjx-H4,108
|
|
170
172
|
castor_extractor/visualization/count/client/queries/canvases.sql,sha256=Ur5HBD9JJH0r14xIj_rwoctnds082_F931vlfcnwi_I,86
|
|
171
173
|
castor_extractor/visualization/count/client/queries/cells.sql,sha256=Kkk0jyU337PD6RPshSo_ucLl5PS7kIvJZlUnVnmJUkM,111
|
|
172
174
|
castor_extractor/visualization/count/client/queries/projects.sql,sha256=3Jem3QCVwk4wHiWRJL7cN6Vl2Yc5RZ8yC8ndvPAkaFM,68
|
|
175
|
+
castor_extractor/visualization/count/client/queries/queries.sql,sha256=ffnlRwMedTVoMzuXkQaTWw5oOP-Ties9vGCfQOXdhQ0,456
|
|
173
176
|
castor_extractor/visualization/count/client/queries/users.sql,sha256=H0n7S7P5cCAWbgPxU32psIc1epXySzsAaQ7MQ9JrkfM,102
|
|
174
177
|
castor_extractor/visualization/count/extract.py,sha256=ZBsJ9tMxxaq1jG8qJp_OGVK3yPDNkVUsP1_3rcUMtYg,1378
|
|
175
178
|
castor_extractor/visualization/domo/__init__.py,sha256=1axOCPm4RpdIyUt9LQEvlMvbOPllW8rk63h6EjVgJ0Y,111
|
|
@@ -285,7 +288,7 @@ castor_extractor/visualization/sigma/__init__.py,sha256=GINql4yJLtjfOJgjHaWNpE13
|
|
|
285
288
|
castor_extractor/visualization/sigma/assets.py,sha256=iVZqi7XtNgSOVXy0jgeHZonVOeXi7jyikor8ztbECBc,398
|
|
286
289
|
castor_extractor/visualization/sigma/client/__init__.py,sha256=YQv06FBBQHvBMFg_tN0nUcmUp2NCL2s-eFTXG8rXaBg,74
|
|
287
290
|
castor_extractor/visualization/sigma/client/authentication.py,sha256=gHukrpfboIjZc_O9CcuDtrl6U-StH0J73VY2J74Bm9o,2279
|
|
288
|
-
castor_extractor/visualization/sigma/client/client.py,sha256=
|
|
291
|
+
castor_extractor/visualization/sigma/client/client.py,sha256=bYlOwtb6ftASb9onUSAHCdEiyfsY5H_KHWkQB4y2Y-o,9063
|
|
289
292
|
castor_extractor/visualization/sigma/client/client_test.py,sha256=ae0ZOvKutCm44jnrJ-0_A5Y6ZGyDkMf9Ml3eEP8dNkY,581
|
|
290
293
|
castor_extractor/visualization/sigma/client/credentials.py,sha256=XddAuQSmCKpxJ70TQgRnOj0vMPYVtiStk_lMMQ1AiNM,693
|
|
291
294
|
castor_extractor/visualization/sigma/client/endpoints.py,sha256=by9VIFml2whlzQT66f2m56RYBsqPrWdAmIP4JkTaBV4,1799
|
|
@@ -326,15 +329,15 @@ castor_extractor/warehouse/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
|
|
|
326
329
|
castor_extractor/warehouse/abstract/__init__.py,sha256=Fdfa026tgOo64MvzVRLHM_F2G-JmcehrF0mh3dHgb7s,419
|
|
327
330
|
castor_extractor/warehouse/abstract/asset.py,sha256=wR5mJxAHBcqJ86HRb_Y8x3mDN4uUgSg8jMToLNu0jTM,2740
|
|
328
331
|
castor_extractor/warehouse/abstract/asset_test.py,sha256=_kd4ybNlWSAdSdEgJKC-jhJTa1nMRa9i8RO3YbqKLM4,758
|
|
329
|
-
castor_extractor/warehouse/abstract/extract.py,sha256=
|
|
330
|
-
castor_extractor/warehouse/abstract/query.py,sha256=
|
|
332
|
+
castor_extractor/warehouse/abstract/extract.py,sha256=a3Poqm1hF6NQQNAWQVib9_uj41LcvXzoX8IQCPCT66c,2922
|
|
333
|
+
castor_extractor/warehouse/abstract/query.py,sha256=h1VvSo6TpyS1myRqmPtoIFY1fVgbthsHOkkajUz-PKA,2444
|
|
331
334
|
castor_extractor/warehouse/abstract/time_filter.py,sha256=bggIONfMmUxffkA6TwM3BsjfS2l9WFxPq8krfsau5pw,935
|
|
332
335
|
castor_extractor/warehouse/abstract/time_filter_test.py,sha256=PIkegB7KOKBdpc6zIvmyl_CeQyADeFDplyQ8HTNU5LA,448
|
|
333
336
|
castor_extractor/warehouse/bigquery/__init__.py,sha256=PCGNYdi7dHv-SyanUWzRuBp-ypuQ01PkDaQjVnaNhbM,170
|
|
334
337
|
castor_extractor/warehouse/bigquery/client.py,sha256=lPAn6WUwDq0rIPNaMOcabet8C4TYJ93EWZUxX72XrZc,5595
|
|
335
338
|
castor_extractor/warehouse/bigquery/client_test.py,sha256=Ym8e4d--0YQwiVcNUnXLx0X-X6ZznwNMBMbMaDS5oEA,1514
|
|
336
339
|
castor_extractor/warehouse/bigquery/credentials.py,sha256=oCZ8H7qpudKzwM7PRMpVAmWXt7bjIRa8Harmp-ysQJ4,425
|
|
337
|
-
castor_extractor/warehouse/bigquery/extract.py,sha256=
|
|
340
|
+
castor_extractor/warehouse/bigquery/extract.py,sha256=4zdqzUROktteGLEpssxT-23shyD7UqWcrs8Mey5MsXA,3128
|
|
338
341
|
castor_extractor/warehouse/bigquery/queries/.sqlfluff,sha256=ce8UDW2k39v6RBVxgKqjOHHYMoGN9S9f7BCZNHHhox8,30
|
|
339
342
|
castor_extractor/warehouse/bigquery/queries/column.sql,sha256=NxdTnHwomHTEGSc-UoXFKUwg59I9XAOwrSau7JUqGQE,1815
|
|
340
343
|
castor_extractor/warehouse/bigquery/queries/cte/sharded.sql,sha256=-G7_4lxV7UPe72mYlp4HDGeM_fJjZWuXJ7Q0vxvj5_U,1454
|
|
@@ -355,7 +358,7 @@ castor_extractor/warehouse/databricks/client_test.py,sha256=dqEdEAt-6e8CtQ7M2L5v
|
|
|
355
358
|
castor_extractor/warehouse/databricks/credentials.py,sha256=ExtVcl2NpMXTx1Lg8vHQdzQtSEm2aqpg3D1BJrNAUjI,528
|
|
356
359
|
castor_extractor/warehouse/databricks/endpoints.py,sha256=qPoL9CtPFJdwVuW9rJ37nmeMd-nChOBouEVYb4SlaUE,670
|
|
357
360
|
castor_extractor/warehouse/databricks/enums.py,sha256=3T6BbVvbWvfWkD23krsYT1x0kKh1qRzNPl6WpcXe300,274
|
|
358
|
-
castor_extractor/warehouse/databricks/extract.py,sha256=
|
|
361
|
+
castor_extractor/warehouse/databricks/extract.py,sha256=u3WJV5bnVKYhGx_yJ_yYyxZjuMw5uC3ehiM_zQeoQwk,7526
|
|
359
362
|
castor_extractor/warehouse/databricks/format.py,sha256=S3BOcwJubc1pyKr-li26uftUUfsjfrm5Qf4LqmElXVk,6736
|
|
360
363
|
castor_extractor/warehouse/databricks/format_test.py,sha256=ls0IcOElqp_qecAzNbK0zdca7Pms4seCHimbw8NAoAI,3322
|
|
361
364
|
castor_extractor/warehouse/databricks/pagination.py,sha256=sM1G0sN1pf1TPpI0Y3Oew378UGEKVkMRc2Mlu9tDjLo,545
|
|
@@ -418,7 +421,7 @@ castor_extractor/warehouse/snowflake/client.py,sha256=RB72bbl_k91wDU76yrggPK6oeE
|
|
|
418
421
|
castor_extractor/warehouse/snowflake/client_test.py,sha256=ihWtOOAQfh8pu5JTr_EWfqefKOVIaJXznACURzaU1Qs,1432
|
|
419
422
|
castor_extractor/warehouse/snowflake/credentials.py,sha256=u0sZ6xPtcZmmvnUsAejJk-YxGl8BTzX_BlRjRk92BYU,932
|
|
420
423
|
castor_extractor/warehouse/snowflake/credentials_test.py,sha256=Lkc-DHXOvr50KrqAW4nt_x0IA0Mu_CsBVu6ATnzQB6I,673
|
|
421
|
-
castor_extractor/warehouse/snowflake/extract.py,sha256=
|
|
424
|
+
castor_extractor/warehouse/snowflake/extract.py,sha256=E7mJsJneCofYoAgyQpc7Th2gKxsyZm2cRr1iADDAcl0,3656
|
|
422
425
|
castor_extractor/warehouse/snowflake/queries/.sqlfluff,sha256=vttrwcr64JVIuvc7WIg9C54cbOkjg_VjXNR7YnTGOPE,31
|
|
423
426
|
castor_extractor/warehouse/snowflake/queries/column.sql,sha256=Ru-yC0s76I9LehOA4aCZ--xz6D9H1Hyr3OZdILOBHAw,1882
|
|
424
427
|
castor_extractor/warehouse/snowflake/queries/column_lineage.sql,sha256=YKBiZ6zySSNcXLDXwm31EjGIIkkkZc0-S6hI1SRM80o,1179
|
|
@@ -431,8 +434,8 @@ castor_extractor/warehouse/snowflake/queries/user.sql,sha256=88V8eRj1NDaD_ufclsK
|
|
|
431
434
|
castor_extractor/warehouse/snowflake/queries/view_ddl.sql,sha256=eWsci_50cxiYIv3N7BKkbXVM3RoIzqSDtohqRnE5kg4,673
|
|
432
435
|
castor_extractor/warehouse/snowflake/query.py,sha256=C2LTdPwBzMQ_zMncg0Kq4_WkoY7K9as5tvxBDrIOlwI,1763
|
|
433
436
|
castor_extractor/warehouse/sqlserver/__init__.py,sha256=PdOuYznmvKAbfWAm8UdN47MfEsd9jqPi_dDi3WEo1KY,116
|
|
434
|
-
castor_extractor/warehouse/sqlserver/client.py,sha256=
|
|
435
|
-
castor_extractor/warehouse/sqlserver/extract.py,sha256=
|
|
437
|
+
castor_extractor/warehouse/sqlserver/client.py,sha256=ggqcOtGeDk9OMyqx7fO3p-2NsbFG8vT-GoHdRx5Iy_Q,5833
|
|
438
|
+
castor_extractor/warehouse/sqlserver/extract.py,sha256=PlYANeqCUrw3uy3HnMxkPT1W3WyRt-qxY9ECK3Sc2lM,2510
|
|
436
439
|
castor_extractor/warehouse/sqlserver/queries/.sqlfluff,sha256=yy0KQdz8I_67vnXyX8eeWwOWkxTXvHyVKSVwhURktd8,48
|
|
437
440
|
castor_extractor/warehouse/sqlserver/queries/column.sql,sha256=ojiUQQnHXdWMbgaYOcxKBiwfi7rtu_tyamK6r4t4IBM,2929
|
|
438
441
|
castor_extractor/warehouse/sqlserver/queries/database.sql,sha256=4dPeBCn85MEOXr1f-DPXxiI3RvvoE_1n8lsbTs26E0I,150
|
|
@@ -443,8 +446,8 @@ castor_extractor/warehouse/sqlserver/queries/user.sql,sha256=MAlnTis43E3Amu1e1Oz
|
|
|
443
446
|
castor_extractor/warehouse/sqlserver/queries/view_ddl.sql,sha256=9rynvx6MWg3iZzrWPB7haZfVKEPkxulzryE2g19x804,315
|
|
444
447
|
castor_extractor/warehouse/sqlserver/query.py,sha256=gr5lnZSUm-wSYuVnJlg6fc7jXWirbL-sCiQN9RnAiPQ,1789
|
|
445
448
|
castor_extractor/warehouse/synapse/queries/column.sql,sha256=lNcFoIW3Y0PFOqoOzJEXmPvZvfAsY0AP63Mu2LuPzPo,1351
|
|
446
|
-
castor_extractor-0.25.
|
|
447
|
-
castor_extractor-0.25.
|
|
448
|
-
castor_extractor-0.25.
|
|
449
|
-
castor_extractor-0.25.
|
|
450
|
-
castor_extractor-0.25.
|
|
449
|
+
castor_extractor-0.25.9.dist-info/LICENCE,sha256=sL-IGa4hweyya1HgzMskrRdybbIa2cktzxb5qmUgDg8,8254
|
|
450
|
+
castor_extractor-0.25.9.dist-info/METADATA,sha256=B5If1AjiP00k7LJDYd13LtlfRoDrxPylNJ5AmjWmFTA,29355
|
|
451
|
+
castor_extractor-0.25.9.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
|
452
|
+
castor_extractor-0.25.9.dist-info/entry_points.txt,sha256=qyTrKNByoq2HYi1xbA79OU7qxg-OWPvle8VwDqt-KnE,1869
|
|
453
|
+
castor_extractor-0.25.9.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|