openmetadata-ingestion 1.2.4.0__py3-none-any.whl → 1.3.2.0rc1__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 openmetadata-ingestion might be problematic. Click here for more details.
- airflow_provider_openmetadata/lineage/runner.py +44 -5
- airflow_provider_openmetadata/lineage/status.py +1 -1
- metadata/antlr/split_listener.py +1 -4
- metadata/applications/auto_tagger.py +212 -0
- metadata/cli/app.py +47 -0
- metadata/cli/db_dump.py +7 -3
- metadata/clients/aws_client.py +4 -0
- metadata/clients/azure_client.py +85 -0
- metadata/clients/domo_client.py +0 -2
- metadata/cmd.py +24 -13
- metadata/data_insight/processor/reports/cost_analysis_report_data_processor.py +40 -48
- metadata/data_insight/processor/reports/data_processor.py +1 -0
- metadata/data_insight/processor/reports/entity_report_data_processor.py +8 -2
- metadata/data_insight/processor/reports/web_analytic_report_data_processor.py +4 -0
- metadata/data_insight/producer/cost_analysis_producer.py +78 -14
- metadata/data_insight/producer/entity_producer.py +1 -1
- metadata/data_insight/producer/producer_interface.py +1 -1
- metadata/data_insight/producer/web_analytics_producer.py +1 -1
- metadata/data_insight/source/metadata.py +21 -5
- metadata/data_quality/interface/sqlalchemy/databricks/test_suite_interface.py +29 -0
- metadata/data_quality/interface/sqlalchemy/snowflake/test_suite_interface.py +29 -0
- metadata/data_quality/interface/sqlalchemy/sqa_test_suite_interface.py +6 -6
- metadata/data_quality/interface/sqlalchemy/unity_catalog/test_suite_interface.py +35 -0
- metadata/data_quality/interface/test_suite_interface_factory.py +40 -0
- metadata/data_quality/processor/test_case_runner.py +17 -8
- metadata/data_quality/source/test_suite.py +10 -4
- metadata/data_quality/validations/base_test_handler.py +21 -17
- metadata/data_quality/validations/column/base/columnValueLengthsToBeBetween.py +38 -1
- metadata/data_quality/validations/column/base/columnValuesToBeBetween.py +36 -1
- metadata/data_quality/validations/column/base/columnValuesToBeInSet.py +27 -0
- metadata/data_quality/validations/column/base/columnValuesToBeNotInSet.py +27 -0
- metadata/data_quality/validations/column/base/columnValuesToBeNotNull.py +27 -0
- metadata/data_quality/validations/column/base/columnValuesToBeUnique.py +15 -0
- metadata/data_quality/validations/column/base/columnValuesToMatchRegex.py +27 -0
- metadata/data_quality/validations/column/base/columnValuesToNotMatchRegex.py +27 -0
- metadata/data_quality/validations/column/pandas/columnValueLengthsToBeBetween.py +23 -0
- metadata/data_quality/validations/column/pandas/columnValuesToBeBetween.py +23 -0
- metadata/data_quality/validations/column/pandas/columnValuesToBeInSet.py +11 -0
- metadata/data_quality/validations/column/pandas/columnValuesToBeNotInSet.py +11 -0
- metadata/data_quality/validations/column/pandas/columnValuesToBeNotNull.py +11 -0
- metadata/data_quality/validations/column/pandas/columnValuesToMatchRegex.py +11 -0
- metadata/data_quality/validations/column/pandas/columnValuesToNotMatchRegex.py +11 -0
- metadata/data_quality/validations/column/sqlalchemy/columnValueLengthsToBeBetween.py +27 -0
- metadata/data_quality/validations/column/sqlalchemy/columnValuesToBeBetween.py +23 -0
- metadata/data_quality/validations/column/sqlalchemy/columnValuesToBeInSet.py +11 -0
- metadata/data_quality/validations/column/sqlalchemy/columnValuesToBeNotInSet.py +11 -0
- metadata/data_quality/validations/column/sqlalchemy/columnValuesToBeNotNull.py +11 -0
- metadata/data_quality/validations/column/sqlalchemy/columnValuesToMatchRegex.py +11 -0
- metadata/data_quality/validations/column/sqlalchemy/columnValuesToNotMatchRegex.py +11 -0
- metadata/data_quality/validations/mixins/pandas_validator_mixin.py +13 -2
- metadata/data_quality/validations/mixins/sqa_validator_mixin.py +40 -0
- metadata/data_quality/validations/table/base/tableColumnToMatchSet.py +2 -1
- metadata/data_quality/validations/table/pandas/tableColumnToMatchSet.py +2 -1
- metadata/data_quality/validations/table/sqlalchemy/tableColumnToMatchSet.py +7 -2
- metadata/examples/workflows/bigtable.yaml +32 -0
- metadata/examples/workflows/databricks.yaml +0 -1
- metadata/examples/workflows/datalake_azure_default.yaml +29 -0
- metadata/examples/workflows/mongodb.yaml +4 -2
- metadata/examples/workflows/mstr.yaml +24 -0
- metadata/examples/workflows/sas.yaml +28 -0
- metadata/examples/workflows/unity_catalog.yaml +27 -0
- metadata/examples/workflows/unity_catalog_lineage.yaml +18 -0
- metadata/examples/workflows/unity_catalog_usage.yaml +35 -0
- metadata/generated/antlr/EntityLinkLexer.py +425 -292
- metadata/generated/antlr/EntityLinkListener.py +12 -12
- metadata/generated/antlr/EntityLinkParser.py +228 -103
- metadata/generated/schema/analytics/__init__.py +1 -1
- metadata/generated/schema/analytics/basic.py +1 -1
- metadata/generated/schema/analytics/reportData.py +1 -1
- metadata/generated/schema/analytics/reportDataType/__init__.py +1 -1
- metadata/generated/schema/analytics/reportDataType/aggregatedCostAnalysisReportData.py +1 -1
- metadata/generated/schema/analytics/reportDataType/entityReportData.py +1 -1
- metadata/generated/schema/analytics/reportDataType/rawCostAnalysisReportData.py +1 -1
- metadata/generated/schema/analytics/reportDataType/webAnalyticEntityViewReportData.py +1 -1
- metadata/generated/schema/analytics/reportDataType/webAnalyticUserActivityReportData.py +1 -1
- metadata/generated/schema/analytics/webAnalyticEvent.py +1 -1
- metadata/generated/schema/analytics/webAnalyticEventData.py +1 -1
- metadata/generated/schema/analytics/webAnalyticEventType/__init__.py +1 -1
- metadata/generated/schema/analytics/webAnalyticEventType/customEvent.py +1 -1
- metadata/generated/schema/analytics/webAnalyticEventType/pageViewEvent.py +1 -1
- metadata/generated/schema/api/__init__.py +1 -1
- metadata/generated/schema/api/addGlossaryToAssetsRequest.py +1 -1
- metadata/generated/schema/api/analytics/__init__.py +1 -1
- metadata/generated/schema/api/analytics/createWebAnalyticEvent.py +1 -1
- metadata/generated/schema/api/automations/__init__.py +1 -1
- metadata/generated/schema/api/automations/createWorkflow.py +1 -1
- metadata/generated/schema/api/bulkAssets.py +1 -1
- metadata/generated/schema/api/classification/__init__.py +1 -1
- metadata/generated/schema/api/classification/createClassification.py +1 -1
- metadata/generated/schema/api/classification/createTag.py +1 -1
- metadata/generated/schema/api/classification/loadTags.py +1 -1
- metadata/generated/schema/api/createBot.py +2 -3
- metadata/generated/schema/api/createEventPublisherJob.py +2 -2
- metadata/generated/schema/api/createType.py +1 -1
- metadata/generated/schema/api/data/__init__.py +1 -1
- metadata/generated/schema/api/data/createChart.py +1 -1
- metadata/generated/schema/api/data/createContainer.py +2 -2
- metadata/generated/schema/api/data/createCustomProperty.py +7 -12
- metadata/generated/schema/api/data/createDashboard.py +1 -1
- metadata/generated/schema/api/data/createDashboardDataModel.py +1 -1
- metadata/generated/schema/api/data/createDatabase.py +2 -3
- metadata/generated/schema/api/data/createDatabaseSchema.py +2 -3
- metadata/generated/schema/api/data/createGlossary.py +2 -3
- metadata/generated/schema/api/data/createGlossaryTerm.py +2 -3
- metadata/generated/schema/api/data/createMlModel.py +1 -1
- metadata/generated/schema/api/data/createPipeline.py +2 -2
- metadata/generated/schema/api/data/createQuery.py +2 -2
- metadata/generated/schema/api/data/createSearchIndex.py +1 -1
- metadata/generated/schema/api/data/createStoredProcedure.py +2 -4
- metadata/generated/schema/api/data/createTable.py +2 -2
- metadata/generated/schema/api/data/createTableProfile.py +1 -1
- metadata/generated/schema/api/data/createTopic.py +1 -1
- metadata/generated/schema/api/data/loadGlossary.py +1 -1
- metadata/generated/schema/api/data/restoreEntity.py +1 -1
- metadata/generated/schema/api/dataInsight/__init__.py +1 -1
- metadata/generated/schema/api/dataInsight/createDataInsightChart.py +1 -1
- metadata/generated/schema/api/dataInsight/kpi/__init__.py +1 -1
- metadata/generated/schema/api/dataInsight/kpi/createKpiRequest.py +1 -1
- metadata/generated/schema/api/docStore/__init__.py +1 -1
- metadata/generated/schema/api/docStore/createDocument.py +1 -1
- metadata/generated/schema/api/domains/__init__.py +1 -1
- metadata/generated/schema/api/domains/createDataProduct.py +1 -1
- metadata/generated/schema/api/domains/createDomain.py +1 -1
- metadata/generated/schema/api/feed/__init__.py +1 -1
- metadata/generated/schema/api/feed/closeTask.py +8 -1
- metadata/generated/schema/api/feed/createPost.py +1 -1
- metadata/generated/schema/api/feed/createSuggestion.py +30 -0
- metadata/generated/schema/api/feed/createThread.py +5 -1
- metadata/generated/schema/api/feed/resolveTask.py +12 -1
- metadata/generated/schema/api/feed/threadCount.py +18 -14
- metadata/generated/schema/api/lineage/__init__.py +1 -1
- metadata/generated/schema/api/lineage/addLineage.py +1 -1
- metadata/generated/schema/api/openMetadataServerVersion.py +1 -1
- metadata/generated/schema/api/policies/__init__.py +1 -1
- metadata/generated/schema/api/policies/createPolicy.py +1 -1
- metadata/generated/schema/api/services/__init__.py +1 -1
- metadata/generated/schema/api/services/createDashboardService.py +1 -1
- metadata/generated/schema/api/services/createDatabaseService.py +1 -1
- metadata/generated/schema/api/services/createMessagingService.py +1 -1
- metadata/generated/schema/api/services/createMetadataService.py +1 -1
- metadata/generated/schema/api/services/createMlModelService.py +1 -1
- metadata/generated/schema/api/services/createPipelineService.py +1 -1
- metadata/generated/schema/api/services/createSearchService.py +1 -1
- metadata/generated/schema/api/services/createStorageService.py +1 -1
- metadata/generated/schema/api/services/ingestionPipelines/__init__.py +1 -1
- metadata/generated/schema/api/services/ingestionPipelines/createIngestionPipeline.py +1 -1
- metadata/generated/schema/api/setOwner.py +1 -1
- metadata/generated/schema/api/teams/__init__.py +1 -1
- metadata/generated/schema/api/teams/createPersona.py +1 -1
- metadata/generated/schema/api/teams/createRole.py +2 -3
- metadata/generated/schema/api/teams/createTeam.py +1 -1
- metadata/generated/schema/api/teams/createUser.py +2 -2
- metadata/generated/schema/api/tests/__init__.py +1 -1
- metadata/generated/schema/api/tests/createCustomMetric.py +4 -2
- metadata/generated/schema/api/tests/createLogicalTestCases.py +1 -1
- metadata/generated/schema/api/tests/createTestCase.py +4 -1
- metadata/generated/schema/api/tests/createTestCaseResolutionStatus.py +31 -0
- metadata/generated/schema/api/tests/createTestDefinition.py +2 -1
- metadata/generated/schema/api/tests/createTestSuite.py +1 -1
- metadata/generated/schema/api/voteRequest.py +1 -1
- metadata/generated/schema/auth/__init__.py +1 -1
- metadata/generated/schema/auth/basicAuth.py +1 -1
- metadata/generated/schema/auth/basicLoginRequest.py +1 -1
- metadata/generated/schema/auth/changePasswordRequest.py +1 -1
- metadata/generated/schema/auth/createPersonalToken.py +1 -1
- metadata/generated/schema/auth/emailRequest.py +1 -1
- metadata/generated/schema/auth/emailVerificationToken.py +1 -1
- metadata/generated/schema/auth/generateToken.py +1 -1
- metadata/generated/schema/auth/jwtAuth.py +1 -1
- metadata/generated/schema/auth/loginRequest.py +1 -1
- metadata/generated/schema/auth/logoutRequest.py +1 -1
- metadata/generated/schema/auth/passwordResetRequest.py +3 -3
- metadata/generated/schema/auth/passwordResetToken.py +1 -1
- metadata/generated/schema/auth/personalAccessToken.py +1 -1
- metadata/generated/schema/auth/refreshToken.py +1 -1
- metadata/generated/schema/auth/registrationRequest.py +2 -2
- metadata/generated/schema/auth/revokePersonalToken.py +1 -1
- metadata/generated/schema/auth/revokeToken.py +1 -1
- metadata/generated/schema/auth/serviceTokenEnum.py +1 -1
- metadata/generated/schema/auth/ssoAuth.py +1 -1
- metadata/generated/schema/auth/tokenRefreshRequest.py +1 -1
- metadata/generated/schema/configuration/__init__.py +1 -1
- metadata/generated/schema/configuration/appsPrivateConfiguration.py +32 -0
- metadata/generated/schema/configuration/authConfig.py +1 -1
- metadata/generated/schema/configuration/authenticationConfiguration.py +13 -2
- metadata/generated/schema/configuration/authorizerConfiguration.py +1 -1
- metadata/generated/schema/configuration/changeEventConfiguration.py +1 -1
- metadata/generated/schema/configuration/dataQualityConfiguration.py +16 -0
- metadata/generated/schema/configuration/elasticSearchConfiguration.py +7 -1
- metadata/generated/schema/configuration/eventHandlerConfiguration.py +1 -1
- metadata/generated/schema/configuration/fernetConfiguration.py +1 -1
- metadata/generated/schema/configuration/jwtTokenConfiguration.py +1 -1
- metadata/generated/schema/configuration/kafkaEventConfiguration.py +1 -1
- metadata/generated/schema/configuration/ldapConfiguration.py +28 -2
- metadata/generated/schema/configuration/ldapTrustStoreConfig/__init__.py +1 -1
- metadata/generated/schema/configuration/ldapTrustStoreConfig/customTrustManagerConfig.py +1 -1
- metadata/generated/schema/configuration/ldapTrustStoreConfig/hostNameConfig.py +1 -1
- metadata/generated/schema/configuration/ldapTrustStoreConfig/jvmDefaultConfig.py +1 -1
- metadata/generated/schema/configuration/ldapTrustStoreConfig/trustAllConfig.py +1 -1
- metadata/generated/schema/configuration/ldapTrustStoreConfig/truststoreConfig.py +1 -1
- metadata/generated/schema/configuration/loginConfiguration.py +1 -1
- metadata/generated/schema/configuration/logoConfiguration.py +1 -1
- metadata/generated/schema/configuration/pipelineServiceClientConfiguration.py +1 -1
- metadata/generated/schema/configuration/slackAppConfiguration.py +1 -1
- metadata/generated/schema/configuration/taskNotificationConfiguration.py +1 -1
- metadata/generated/schema/configuration/testResultNotificationConfiguration.py +1 -1
- metadata/generated/schema/dataInsight/__init__.py +1 -1
- metadata/generated/schema/dataInsight/dataInsightChart.py +1 -1
- metadata/generated/schema/dataInsight/dataInsightChartResult.py +1 -1
- metadata/generated/schema/dataInsight/kpi/__init__.py +1 -1
- metadata/generated/schema/dataInsight/kpi/basic.py +1 -1
- metadata/generated/schema/dataInsight/kpi/kpi.py +1 -1
- metadata/generated/schema/dataInsight/type/__init__.py +1 -1
- metadata/generated/schema/dataInsight/type/aggregatedUnusedAssetsCount.py +1 -1
- metadata/generated/schema/dataInsight/type/aggregatedUnusedAssetsSize.py +1 -1
- metadata/generated/schema/dataInsight/type/aggregatedUsedVsUnusedAssetsCount.py +1 -1
- metadata/generated/schema/dataInsight/type/aggregatedUsedVsUnusedAssetsSize.py +1 -1
- metadata/generated/schema/dataInsight/type/dailyActiveUsers.py +1 -1
- metadata/generated/schema/dataInsight/type/mostActiveUsers.py +1 -1
- metadata/generated/schema/dataInsight/type/mostViewedEntities.py +1 -1
- metadata/generated/schema/dataInsight/type/pageViewsByEntities.py +1 -1
- metadata/generated/schema/dataInsight/type/percentageOfEntitiesWithDescriptionByType.py +1 -1
- metadata/generated/schema/dataInsight/type/percentageOfEntitiesWithOwnerByType.py +1 -1
- metadata/generated/schema/dataInsight/type/percentageOfServicesWithDescription.py +1 -1
- metadata/generated/schema/dataInsight/type/percentageOfServicesWithOwner.py +1 -1
- metadata/generated/schema/dataInsight/type/totalEntitiesByTier.py +1 -1
- metadata/generated/schema/dataInsight/type/totalEntitiesByType.py +1 -1
- metadata/generated/schema/dataInsight/type/unusedAssets.py +1 -1
- metadata/generated/schema/email/__init__.py +1 -1
- metadata/generated/schema/email/emailRequest.py +1 -1
- metadata/generated/schema/email/smtpSettings.py +1 -1
- metadata/generated/schema/entity/__init__.py +1 -1
- metadata/generated/schema/entity/applications/__init__.py +1 -1
- metadata/generated/schema/entity/applications/app.py +24 -5
- metadata/generated/schema/entity/applications/appRunRecord.py +2 -7
- metadata/generated/schema/entity/applications/configuration/__init__.py +1 -1
- metadata/generated/schema/entity/applications/configuration/applicationConfig.py +30 -0
- metadata/generated/schema/entity/{services/connections/database/mongoDB → applications/configuration/external}/__init__.py +1 -1
- metadata/generated/schema/entity/applications/configuration/external/autoTaggerAppConfig.py +28 -0
- metadata/generated/schema/entity/applications/configuration/external/metaPilotAppConfig.py +46 -0
- metadata/generated/schema/entity/applications/configuration/internal/__init__.py +3 -0
- metadata/generated/schema/entity/applications/configuration/internal/dataInsightsAppConfig.py +14 -0
- metadata/generated/schema/entity/applications/configuration/internal/dataInsightsReportAppConfig.py +27 -0
- metadata/generated/schema/entity/applications/configuration/{searchIndexingApp.py → internal/searchIndexingAppConfig.py} +14 -4
- metadata/generated/schema/entity/applications/configuration/private/external/__init__.py +3 -0
- metadata/generated/schema/entity/applications/configuration/private/external/metaPilotAppPrivateConfig.py +26 -0
- metadata/generated/schema/entity/applications/createAppRequest.py +1 -1
- metadata/generated/schema/entity/applications/jobStatus.py +3 -3
- metadata/generated/schema/entity/applications/liveExecutionContext.py +1 -1
- metadata/generated/schema/entity/applications/marketplace/__init__.py +1 -1
- metadata/generated/schema/entity/applications/marketplace/appMarketPlaceDefinition.py +12 -3
- metadata/generated/schema/entity/applications/marketplace/createAppMarketPlaceDefinitionReq.py +12 -3
- metadata/generated/schema/entity/applications/scheduledExecutionContext.py +1 -1
- metadata/generated/schema/entity/automations/__init__.py +1 -1
- metadata/generated/schema/entity/automations/testServiceConnection.py +2 -2
- metadata/generated/schema/entity/automations/workflow.py +1 -1
- metadata/generated/schema/entity/bot.py +2 -3
- metadata/generated/schema/entity/classification/__init__.py +1 -1
- metadata/generated/schema/entity/classification/classification.py +1 -1
- metadata/generated/schema/entity/classification/tag.py +2 -2
- metadata/generated/schema/entity/data/__init__.py +1 -1
- metadata/generated/schema/entity/data/chart.py +1 -1
- metadata/generated/schema/entity/data/container.py +4 -9
- metadata/generated/schema/entity/data/dashboard.py +1 -1
- metadata/generated/schema/entity/data/dashboardDataModel.py +1 -1
- metadata/generated/schema/entity/data/database.py +4 -8
- metadata/generated/schema/entity/data/databaseSchema.py +2 -8
- metadata/generated/schema/entity/data/glossary.py +1 -1
- metadata/generated/schema/entity/data/glossaryTerm.py +1 -1
- metadata/generated/schema/entity/data/metrics.py +1 -1
- metadata/generated/schema/entity/data/mlmodel.py +2 -2
- metadata/generated/schema/entity/data/pipeline.py +6 -9
- metadata/generated/schema/entity/data/query.py +2 -2
- metadata/generated/schema/entity/data/report.py +1 -1
- metadata/generated/schema/entity/data/searchIndex.py +1 -1
- metadata/generated/schema/entity/data/storedProcedure.py +3 -9
- metadata/generated/schema/entity/data/table.py +18 -12
- metadata/generated/schema/entity/data/topic.py +1 -1
- metadata/generated/schema/entity/docStore/__init__.py +1 -1
- metadata/generated/schema/entity/docStore/document.py +1 -1
- metadata/generated/schema/entity/domains/__init__.py +1 -1
- metadata/generated/schema/entity/domains/dataProduct.py +1 -1
- metadata/generated/schema/entity/domains/domain.py +1 -1
- metadata/generated/schema/entity/events/__init__.py +1 -1
- metadata/generated/schema/entity/events/webhook.py +6 -3
- metadata/generated/schema/entity/feed/__init__.py +1 -1
- metadata/generated/schema/entity/feed/suggestion.py +61 -0
- metadata/generated/schema/entity/feed/thread.py +17 -1
- metadata/generated/schema/entity/policies/__init__.py +1 -1
- metadata/generated/schema/entity/policies/accessControl/__init__.py +1 -1
- metadata/generated/schema/entity/policies/accessControl/resourceDescriptor.py +1 -1
- metadata/generated/schema/entity/policies/accessControl/resourcePermission.py +1 -1
- metadata/generated/schema/entity/policies/accessControl/rule.py +1 -1
- metadata/generated/schema/entity/policies/filters.py +2 -5
- metadata/generated/schema/entity/policies/policy.py +1 -1
- metadata/generated/schema/entity/services/__init__.py +1 -1
- metadata/generated/schema/entity/services/connections/__init__.py +1 -1
- metadata/generated/schema/entity/services/connections/common/__init__.py +1 -1
- metadata/generated/schema/entity/services/connections/common/sslCertPaths.py +1 -1
- metadata/generated/schema/entity/services/connections/common/sslCertValues.py +1 -1
- metadata/generated/schema/entity/services/connections/common/sslConfig.py +1 -1
- metadata/generated/schema/entity/services/connections/connectionBasicType.py +1 -1
- metadata/generated/schema/entity/services/connections/dashboard/__init__.py +1 -1
- metadata/generated/schema/entity/services/connections/dashboard/customDashboardConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/dashboard/domoDashboardConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/dashboard/lightdashConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/dashboard/lookerConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/dashboard/metabaseConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/dashboard/modeConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/dashboard/mstrConnection.py +46 -0
- metadata/generated/schema/entity/services/connections/dashboard/powerBIConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/dashboard/qlikSenseConnection.py +2 -2
- metadata/generated/schema/entity/services/connections/dashboard/quickSightConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/dashboard/redashConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/dashboard/supersetConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/dashboard/tableauConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/database/__init__.py +1 -1
- metadata/generated/schema/entity/services/connections/database/athenaConnection.py +2 -2
- metadata/generated/schema/entity/services/connections/database/azureSQLConnection.py +35 -2
- metadata/generated/schema/entity/services/connections/database/bigQueryConnection.py +2 -2
- metadata/generated/schema/entity/services/connections/database/bigTableConnection.py +41 -0
- metadata/generated/schema/entity/services/connections/database/clickhouseConnection.py +2 -2
- metadata/generated/schema/entity/services/connections/database/common/__init__.py +1 -1
- metadata/generated/schema/entity/services/connections/database/common/azureConfig.py +20 -0
- metadata/generated/schema/entity/services/connections/database/common/basicAuth.py +1 -1
- metadata/generated/schema/entity/services/connections/database/common/iamAuthConfig.py +1 -1
- metadata/generated/schema/entity/services/connections/database/common/jwtAuth.py +1 -1
- metadata/generated/schema/entity/services/connections/database/couchbaseConnection.py +6 -1
- metadata/generated/schema/entity/services/connections/database/customDatabaseConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/database/databricksConnection.py +2 -7
- metadata/generated/schema/entity/services/connections/database/datalake/__init__.py +1 -1
- metadata/generated/schema/entity/services/connections/database/datalake/azureConfig.py +1 -1
- metadata/generated/schema/entity/services/connections/database/datalake/gcsConfig.py +1 -1
- metadata/generated/schema/entity/services/connections/database/datalake/s3Config.py +1 -1
- metadata/generated/schema/entity/services/connections/database/datalakeConnection.py +2 -2
- metadata/generated/schema/entity/services/connections/database/db2Connection.py +3 -2
- metadata/generated/schema/entity/services/connections/database/deltaLakeConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/database/domoDatabaseConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/database/dorisConnection.py +86 -0
- metadata/generated/schema/entity/services/connections/database/druidConnection.py +2 -2
- metadata/generated/schema/entity/services/connections/database/dynamoDBConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/database/glueConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/database/greenplumConnection.py +2 -2
- metadata/generated/schema/entity/services/connections/database/hiveConnection.py +2 -2
- metadata/generated/schema/entity/services/connections/database/iceberg/__init__.py +3 -0
- metadata/generated/schema/entity/services/connections/database/iceberg/dynamoDbCatalogConnection.py +17 -0
- metadata/generated/schema/entity/services/connections/database/iceberg/glueCatalogConnection.py +16 -0
- metadata/generated/schema/entity/services/connections/database/iceberg/hiveCatalogConnection.py +23 -0
- metadata/generated/schema/entity/services/connections/database/iceberg/icebergCatalog.py +43 -0
- metadata/generated/schema/entity/services/connections/database/iceberg/icebergFileSystem.py +20 -0
- metadata/generated/schema/entity/services/connections/database/iceberg/restCatalogConnection.py +69 -0
- metadata/generated/schema/entity/services/connections/database/icebergConnection.py +35 -0
- metadata/generated/schema/entity/services/connections/database/impalaConnection.py +2 -2
- metadata/generated/schema/entity/services/connections/database/mariaDBConnection.py +2 -2
- metadata/generated/schema/entity/services/connections/database/mongoDBConnection.py +24 -14
- metadata/generated/schema/entity/services/connections/database/mssqlConnection.py +5 -2
- metadata/generated/schema/entity/services/connections/database/mysqlConnection.py +8 -4
- metadata/generated/schema/entity/services/connections/database/oracleConnection.py +2 -2
- metadata/generated/schema/entity/services/connections/database/pinotDBConnection.py +9 -7
- metadata/generated/schema/entity/services/connections/database/postgresConnection.py +8 -4
- metadata/generated/schema/entity/services/connections/database/prestoConnection.py +2 -2
- metadata/generated/schema/entity/services/connections/database/redshiftConnection.py +2 -2
- metadata/generated/schema/entity/services/connections/database/salesforceConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/database/sapHana/__init__.py +3 -0
- metadata/generated/schema/entity/services/connections/database/sapHana/sapHanaHDBConnection.py +20 -0
- metadata/generated/schema/entity/services/connections/database/sapHana/sapHanaSQLConnection.py +36 -0
- metadata/generated/schema/entity/services/connections/database/sapHanaConnection.py +7 -41
- metadata/generated/schema/entity/services/connections/database/sasConnection.py +48 -0
- metadata/generated/schema/entity/services/connections/database/singleStoreConnection.py +2 -2
- metadata/generated/schema/entity/services/connections/database/snowflakeConnection.py +2 -2
- metadata/generated/schema/entity/services/connections/database/sqliteConnection.py +2 -2
- metadata/generated/schema/entity/services/connections/database/trinoConnection.py +2 -2
- metadata/generated/schema/entity/services/connections/database/unityCatalogConnection.py +90 -0
- metadata/generated/schema/entity/services/connections/database/verticaConnection.py +2 -2
- metadata/generated/schema/entity/services/connections/messaging/__init__.py +1 -1
- metadata/generated/schema/entity/services/connections/messaging/customMessagingConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/messaging/kafkaConnection.py +14 -2
- metadata/generated/schema/entity/services/connections/messaging/kinesisConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/messaging/pulsarConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/messaging/redpandaConnection.py +14 -2
- metadata/generated/schema/entity/services/connections/messaging/saslMechanismType.py +1 -1
- metadata/generated/schema/entity/services/connections/metadata/__init__.py +1 -1
- metadata/generated/schema/entity/services/connections/metadata/alationConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/metadata/amundsenConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/metadata/atlasConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/metadata/metadataESConnection.py +2 -2
- metadata/generated/schema/entity/services/connections/metadata/openMetadataConnection.py +5 -20
- metadata/generated/schema/entity/services/connections/mlmodel/__init__.py +1 -1
- metadata/generated/schema/entity/services/connections/mlmodel/customMlModelConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/mlmodel/mlflowConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/mlmodel/sageMakerConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/mlmodel/sklearnConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/pipeline/__init__.py +1 -1
- metadata/generated/schema/entity/services/connections/pipeline/airbyteConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/pipeline/airflowConnection.py +2 -8
- metadata/generated/schema/entity/services/connections/pipeline/backendConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/pipeline/customPipelineConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/pipeline/dagsterConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/pipeline/databricksPipelineConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/pipeline/domoPipelineConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/pipeline/fivetranConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/pipeline/gluePipelineConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/pipeline/nifiConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/pipeline/sparkConnection.py +23 -0
- metadata/generated/schema/entity/services/connections/pipeline/splineConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/search/__init__.py +1 -1
- metadata/generated/schema/entity/services/connections/search/customSearchConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/search/elasticSearch/__init__.py +1 -1
- metadata/generated/schema/entity/services/connections/search/elasticSearch/apiAuth.py +1 -1
- metadata/generated/schema/entity/services/connections/search/elasticSearch/basicAuth.py +1 -1
- metadata/generated/schema/entity/services/connections/search/elasticSearchConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/search/openSearchConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/serviceConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/storage/__init__.py +1 -1
- metadata/generated/schema/entity/services/connections/storage/{adlsConection.py → adlsConnection.py} +2 -2
- metadata/generated/schema/entity/services/connections/storage/customStorageConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/storage/gcsConnection.py +1 -1
- metadata/generated/schema/entity/services/connections/storage/s3Connection.py +1 -1
- metadata/generated/schema/entity/services/connections/testConnectionDefinition.py +1 -1
- metadata/generated/schema/entity/services/connections/testConnectionResult.py +1 -1
- metadata/generated/schema/entity/services/dashboardService.py +4 -1
- metadata/generated/schema/entity/services/databaseService.py +16 -1
- metadata/generated/schema/entity/services/ingestionPipelines/__init__.py +1 -1
- metadata/generated/schema/entity/services/ingestionPipelines/ingestionPipeline.py +27 -22
- metadata/generated/schema/entity/services/ingestionPipelines/pipelineServiceClientResponse.py +1 -1
- metadata/generated/schema/entity/services/ingestionPipelines/status.py +56 -0
- metadata/generated/schema/entity/services/messagingService.py +1 -1
- metadata/generated/schema/entity/services/metadataService.py +1 -1
- metadata/generated/schema/entity/services/mlmodelService.py +1 -1
- metadata/generated/schema/entity/services/pipelineService.py +4 -1
- metadata/generated/schema/entity/services/searchService.py +1 -1
- metadata/generated/schema/entity/services/serviceType.py +1 -1
- metadata/generated/schema/entity/services/storageService.py +10 -3
- metadata/generated/schema/entity/teams/__init__.py +1 -1
- metadata/generated/schema/entity/teams/persona.py +1 -1
- metadata/generated/schema/entity/teams/role.py +2 -6
- metadata/generated/schema/entity/teams/team.py +1 -1
- metadata/generated/schema/entity/teams/teamHierarchy.py +1 -1
- metadata/generated/schema/entity/teams/user.py +3 -10
- metadata/generated/schema/entity/type.py +4 -19
- metadata/generated/schema/entity/utils/__init__.py +1 -1
- metadata/generated/schema/entity/utils/entitiesCount.py +1 -1
- metadata/generated/schema/entity/utils/servicesCount.py +1 -1
- metadata/generated/schema/entity/utils/supersetApiConnection.py +1 -1
- metadata/generated/schema/events/__init__.py +1 -1
- metadata/generated/schema/events/alertMetrics.py +27 -0
- metadata/generated/schema/events/api/__init__.py +1 -1
- metadata/generated/schema/events/api/createEventSubscription.py +14 -12
- metadata/generated/schema/events/emailAlertConfig.py +1 -1
- metadata/generated/schema/events/eventFilterRule.py +13 -2
- metadata/generated/schema/events/eventSubscription.py +91 -49
- metadata/generated/schema/events/eventSubscriptionOffset.py +21 -0
- metadata/generated/schema/events/failedEvent.py +26 -0
- metadata/generated/schema/events/filterResourceDescriptor.py +27 -0
- metadata/generated/schema/events/subscriptionResourceDescriptor.py +11 -10
- metadata/generated/schema/metadataIngestion/__init__.py +1 -1
- metadata/generated/schema/metadataIngestion/application.py +40 -0
- metadata/generated/schema/metadataIngestion/applicationPipeline.py +15 -6
- metadata/generated/schema/metadataIngestion/dashboardServiceMetadataPipeline.py +1 -1
- metadata/generated/schema/metadataIngestion/dataInsightPipeline.py +1 -1
- metadata/generated/schema/metadataIngestion/databaseServiceMetadataPipeline.py +6 -1
- metadata/generated/schema/metadataIngestion/databaseServiceProfilerPipeline.py +11 -1
- metadata/generated/schema/metadataIngestion/databaseServiceQueryLineagePipeline.py +1 -1
- metadata/generated/schema/metadataIngestion/databaseServiceQueryUsagePipeline.py +1 -1
- metadata/generated/schema/metadataIngestion/dbtPipeline.py +1 -1
- metadata/generated/schema/metadataIngestion/dbtconfig/__init__.py +1 -1
- metadata/generated/schema/metadataIngestion/dbtconfig/dbtAzureConfig.py +6 -3
- metadata/generated/schema/metadataIngestion/dbtconfig/dbtBucketDetails.py +1 -1
- metadata/generated/schema/metadataIngestion/dbtconfig/dbtCloudConfig.py +1 -1
- metadata/generated/schema/metadataIngestion/dbtconfig/dbtGCSConfig.py +6 -3
- metadata/generated/schema/metadataIngestion/dbtconfig/dbtHttpConfig.py +1 -1
- metadata/generated/schema/metadataIngestion/dbtconfig/dbtLocalConfig.py +1 -1
- metadata/generated/schema/metadataIngestion/dbtconfig/dbtS3Config.py +6 -3
- metadata/generated/schema/metadataIngestion/messagingServiceMetadataPipeline.py +1 -1
- metadata/generated/schema/metadataIngestion/metadataToElasticSearchPipeline.py +1 -1
- metadata/generated/schema/metadataIngestion/mlmodelServiceMetadataPipeline.py +1 -1
- metadata/generated/schema/metadataIngestion/pipelineServiceMetadataPipeline.py +1 -1
- metadata/generated/schema/metadataIngestion/searchServiceMetadataPipeline.py +1 -1
- metadata/generated/schema/metadataIngestion/storage/__init__.py +1 -1
- metadata/generated/schema/metadataIngestion/storage/containerMetadataConfig.py +1 -1
- metadata/generated/schema/metadataIngestion/storage/manifestMetadataConfig.py +1 -1
- metadata/generated/schema/metadataIngestion/storage/storageBucketDetails.py +1 -1
- metadata/generated/schema/metadataIngestion/storage/storageMetadataADLSConfig.py +2 -2
- metadata/generated/schema/metadataIngestion/storage/storageMetadataGCSConfig.py +24 -0
- metadata/generated/schema/metadataIngestion/storage/storageMetadataHttpConfig.py +1 -1
- metadata/generated/schema/metadataIngestion/storage/storageMetadataLocalConfig.py +1 -1
- metadata/generated/schema/metadataIngestion/storage/storageMetadataS3Config.py +1 -1
- metadata/generated/schema/metadataIngestion/storageServiceMetadataPipeline.py +8 -1
- metadata/generated/schema/metadataIngestion/testSuitePipeline.py +1 -1
- metadata/generated/schema/metadataIngestion/workflow.py +1 -1
- metadata/generated/schema/monitoring/__init__.py +1 -1
- metadata/generated/schema/monitoring/eventMonitorProvider.py +1 -1
- metadata/generated/schema/security/__init__.py +1 -1
- metadata/generated/schema/security/client/__init__.py +1 -1
- metadata/generated/schema/security/client/auth0SSOClientConfig.py +1 -1
- metadata/generated/schema/security/client/azureSSOClientConfig.py +1 -1
- metadata/generated/schema/security/client/customOidcSSOClientConfig.py +1 -1
- metadata/generated/schema/security/client/googleSSOClientConfig.py +1 -1
- metadata/generated/schema/security/client/oidcClientConfig.py +46 -0
- metadata/generated/schema/security/client/oktaSSOClientConfig.py +1 -1
- metadata/generated/schema/security/client/openMetadataJWTClientConfig.py +1 -1
- metadata/generated/schema/security/client/samlSSOClientConfig.py +1 -1
- metadata/generated/schema/security/credentials/__init__.py +1 -1
- metadata/generated/schema/security/credentials/accessTokenAuth.py +1 -1
- metadata/generated/schema/security/credentials/apiAccessTokenAuth.py +1 -1
- metadata/generated/schema/security/credentials/awsCredentials.py +1 -1
- metadata/generated/schema/security/credentials/azureCredentials.py +21 -9
- metadata/generated/schema/security/credentials/basicAuth.py +1 -1
- metadata/generated/schema/security/credentials/bitbucketCredentials.py +1 -1
- metadata/generated/schema/security/credentials/gcpCredentials.py +7 -3
- metadata/generated/schema/security/credentials/gcpExternalAccount.py +37 -0
- metadata/generated/schema/security/credentials/gcpValues.py +2 -2
- metadata/generated/schema/security/credentials/gitCredentials.py +1 -1
- metadata/generated/schema/security/credentials/githubCredentials.py +1 -1
- metadata/generated/schema/security/secrets/__init__.py +1 -1
- metadata/generated/schema/security/secrets/secretsManagerClientLoader.py +1 -1
- metadata/generated/schema/security/secrets/secretsManagerConfiguration.py +14 -4
- metadata/generated/schema/security/secrets/secretsManagerProvider.py +4 -2
- metadata/generated/schema/security/securityConfiguration.py +1 -1
- metadata/generated/schema/security/ssl/__init__.py +1 -1
- metadata/generated/schema/security/ssl/validateSSLClientConfig.py +1 -1
- metadata/generated/schema/security/ssl/verifySSLConfig.py +4 -1
- metadata/generated/schema/settings/__init__.py +1 -1
- metadata/generated/schema/settings/settings.py +1 -1
- metadata/generated/schema/system/__init__.py +1 -1
- metadata/generated/schema/system/entityError.py +17 -0
- metadata/generated/schema/system/eventPublisherJob.py +5 -19
- metadata/generated/schema/system/indexingError.py +34 -0
- metadata/generated/schema/system/ui/__init__.py +1 -1
- metadata/generated/schema/system/ui/knowledgePanel.py +1 -1
- metadata/generated/schema/system/ui/page.py +1 -1
- metadata/generated/schema/system/validationResponse.py +43 -0
- metadata/generated/schema/tests/__init__.py +1 -1
- metadata/generated/schema/tests/assigned.py +18 -0
- metadata/generated/schema/tests/basic.py +17 -39
- metadata/generated/schema/tests/customMetric.py +4 -2
- metadata/generated/schema/tests/resolved.py +35 -0
- metadata/generated/schema/tests/testCase.py +11 -2
- metadata/generated/schema/tests/testCaseResolutionStatus.py +63 -0
- metadata/generated/schema/tests/testDefinition.py +6 -1
- metadata/generated/schema/tests/testSuite.py +1 -1
- metadata/generated/schema/type/__init__.py +1 -1
- metadata/generated/schema/type/auditLog.py +1 -1
- metadata/generated/schema/type/basic.py +10 -6
- metadata/generated/schema/type/bulkOperationResult.py +1 -1
- metadata/generated/schema/type/changeEvent.py +5 -75
- metadata/generated/schema/type/changeEventType.py +29 -0
- metadata/generated/schema/type/collectionDescriptor.py +1 -1
- metadata/generated/schema/type/csvDocumentation.py +1 -1
- metadata/generated/schema/type/csvErrorType.py +1 -1
- metadata/generated/schema/type/csvFile.py +1 -1
- metadata/generated/schema/type/csvImportResult.py +1 -1
- metadata/generated/schema/type/customProperties/__init__.py +3 -0
- metadata/generated/schema/type/customProperties/enumConfig.py +17 -0
- metadata/generated/schema/type/customProperty.py +52 -0
- metadata/generated/schema/type/dailyCount.py +1 -1
- metadata/generated/schema/type/databaseConnectionConfig.py +1 -1
- metadata/generated/schema/type/entityHistory.py +1 -1
- metadata/generated/schema/type/entityLineage.py +2 -1
- metadata/generated/schema/type/entityReference.py +5 -1
- metadata/generated/schema/type/entityReferenceList.py +1 -1
- metadata/generated/schema/type/entityRelationship.py +1 -1
- metadata/generated/schema/type/entityUsage.py +1 -1
- metadata/generated/schema/type/filterPattern.py +1 -1
- metadata/generated/schema/type/function.py +7 -6
- metadata/generated/schema/type/include.py +1 -1
- metadata/generated/schema/type/jdbcConnection.py +1 -1
- metadata/generated/schema/type/lifeCycle.py +1 -1
- metadata/generated/schema/type/paging.py +1 -1
- metadata/generated/schema/type/profile.py +1 -1
- metadata/generated/schema/type/queryParserData.py +2 -2
- metadata/generated/schema/type/reaction.py +1 -1
- metadata/generated/schema/type/schedule.py +1 -1
- metadata/generated/schema/type/schema.py +1 -1
- metadata/generated/schema/type/tableQuery.py +2 -2
- metadata/generated/schema/type/tableUsageCount.py +1 -1
- metadata/generated/schema/type/tagLabel.py +1 -1
- metadata/generated/schema/type/usageDetails.py +1 -1
- metadata/generated/schema/type/usageRequest.py +1 -1
- metadata/generated/schema/type/votes.py +1 -1
- metadata/great_expectations/action.py +12 -20
- metadata/ingestion/api/delete.py +5 -2
- metadata/ingestion/api/models.py +4 -10
- metadata/ingestion/api/parser.py +3 -37
- metadata/ingestion/api/status.py +15 -4
- metadata/ingestion/api/step.py +39 -6
- metadata/ingestion/api/steps.py +34 -1
- metadata/ingestion/api/topology_runner.py +117 -168
- metadata/ingestion/bulksink/metadata_usage.py +11 -5
- metadata/ingestion/lineage/models.py +4 -0
- metadata/ingestion/lineage/parser.py +28 -12
- metadata/ingestion/lineage/sql_lineage.py +9 -17
- metadata/ingestion/models/custom_properties.py +0 -1
- metadata/ingestion/models/custom_pydantic.py +4 -2
- metadata/ingestion/models/lf_tags_model.py +33 -0
- metadata/ingestion/models/patch_request.py +160 -2
- metadata/ingestion/models/tests_data.py +9 -0
- metadata/ingestion/models/topology.py +177 -60
- metadata/ingestion/ometa/auth_provider.py +0 -349
- metadata/ingestion/ometa/client.py +12 -3
- metadata/ingestion/ometa/mixins/custom_property_mixin.py +11 -11
- metadata/ingestion/ometa/mixins/es_mixin.py +17 -0
- metadata/ingestion/ometa/mixins/patch_mixin.py +21 -72
- metadata/ingestion/ometa/mixins/suggestions_mixin.py +41 -0
- metadata/ingestion/ometa/mixins/table_mixin.py +18 -0
- metadata/ingestion/ometa/mixins/tests_mixin.py +24 -3
- metadata/ingestion/ometa/mixins/user_mixin.py +117 -22
- metadata/ingestion/ometa/ometa_api.py +19 -26
- metadata/ingestion/ometa/routes.py +7 -0
- metadata/ingestion/processor/query_parser.py +9 -2
- metadata/ingestion/sink/metadata_rest.py +29 -8
- metadata/ingestion/source/dashboard/dashboard_service.py +38 -61
- metadata/ingestion/source/dashboard/domodashboard/metadata.py +13 -14
- metadata/ingestion/source/dashboard/lightdash/metadata.py +2 -1
- metadata/ingestion/source/dashboard/looker/metadata.py +41 -29
- metadata/ingestion/source/dashboard/looker/utils.py +4 -2
- metadata/ingestion/source/dashboard/metabase/client.py +4 -0
- metadata/ingestion/source/dashboard/metabase/metadata.py +28 -10
- metadata/ingestion/source/dashboard/metabase/models.py +2 -2
- metadata/ingestion/source/dashboard/mode/client.py +10 -23
- metadata/ingestion/source/dashboard/mode/connection.py +6 -1
- metadata/ingestion/source/dashboard/mode/metadata.py +8 -4
- metadata/ingestion/source/dashboard/mstr/client.py +208 -0
- metadata/ingestion/source/dashboard/mstr/connection.py +53 -0
- metadata/ingestion/source/dashboard/mstr/metadata.py +182 -0
- metadata/ingestion/source/dashboard/mstr/models.py +144 -0
- metadata/ingestion/source/dashboard/powerbi/client.py +4 -1
- metadata/ingestion/source/dashboard/powerbi/metadata.py +15 -10
- metadata/ingestion/source/dashboard/qliksense/metadata.py +11 -7
- metadata/ingestion/source/dashboard/quicksight/metadata.py +9 -5
- metadata/ingestion/source/dashboard/redash/metadata.py +23 -14
- metadata/ingestion/source/dashboard/superset/api_source.py +11 -8
- metadata/ingestion/source/dashboard/superset/client.py +16 -9
- metadata/ingestion/source/dashboard/superset/connection.py +3 -3
- metadata/ingestion/source/dashboard/superset/db_source.py +14 -11
- metadata/ingestion/source/dashboard/superset/mixin.py +22 -18
- metadata/ingestion/source/dashboard/superset/queries.py +1 -1
- metadata/ingestion/source/dashboard/tableau/client.py +91 -11
- metadata/ingestion/source/dashboard/tableau/connection.py +10 -1
- metadata/ingestion/source/dashboard/tableau/metadata.py +76 -70
- metadata/ingestion/source/dashboard/tableau/models.py +0 -8
- metadata/ingestion/source/dashboard/tableau/queries.py +5 -5
- metadata/ingestion/source/database/athena/client.py +80 -0
- metadata/ingestion/source/database/athena/connection.py +7 -0
- metadata/ingestion/source/database/athena/metadata.py +161 -19
- metadata/ingestion/source/database/azuresql/connection.py +21 -3
- metadata/ingestion/source/database/azuresql/metadata.py +0 -1
- metadata/ingestion/source/database/bigquery/connection.py +24 -3
- metadata/ingestion/source/database/bigquery/helper.py +68 -1
- metadata/ingestion/source/database/bigquery/metadata.py +49 -28
- metadata/ingestion/source/database/bigquery/queries.py +33 -4
- metadata/ingestion/source/database/bigquery/query_parser.py +13 -0
- metadata/ingestion/source/database/bigquery/usage.py +1 -3
- metadata/ingestion/source/database/bigtable/client.py +62 -0
- metadata/ingestion/source/database/bigtable/connection.py +116 -0
- metadata/ingestion/source/database/bigtable/metadata.py +224 -0
- metadata/ingestion/source/database/bigtable/models.py +60 -0
- metadata/ingestion/source/database/column_helpers.py +0 -10
- metadata/ingestion/source/database/column_type_parser.py +11 -5
- metadata/ingestion/source/database/common_db_source.py +33 -8
- metadata/ingestion/source/database/common_nosql_source.py +27 -6
- metadata/ingestion/source/database/database_service.py +89 -7
- metadata/ingestion/source/database/databricks/client.py +55 -103
- metadata/ingestion/source/database/databricks/connection.py +16 -55
- metadata/ingestion/source/database/databricks/lineage.py +29 -26
- metadata/ingestion/source/database/databricks/metadata.py +534 -11
- metadata/ingestion/source/database/databricks/queries.py +27 -0
- metadata/ingestion/source/database/databricks/query_parser.py +5 -1
- metadata/ingestion/source/database/databricks/usage.py +3 -3
- metadata/ingestion/source/database/datalake/connection.py +33 -18
- metadata/ingestion/source/database/datalake/metadata.py +113 -27
- metadata/ingestion/source/database/dbt/dbt_config.py +7 -14
- metadata/ingestion/source/database/dbt/dbt_service.py +10 -14
- metadata/ingestion/source/database/dbt/dbt_utils.py +3 -1
- metadata/ingestion/source/database/dbt/metadata.py +27 -53
- metadata/ingestion/source/database/deltalake/metadata.py +6 -3
- metadata/ingestion/source/database/domodatabase/metadata.py +7 -6
- metadata/ingestion/source/database/doris/connection.py +72 -0
- metadata/ingestion/source/database/doris/metadata.py +315 -0
- metadata/ingestion/source/database/doris/queries.py +54 -0
- metadata/ingestion/source/database/doris/utils.py +64 -0
- metadata/ingestion/source/database/extended_sample_data.py +532 -0
- metadata/ingestion/source/database/glue/metadata.py +8 -5
- metadata/ingestion/source/database/hive/connection.py +0 -2
- metadata/ingestion/source/database/hive/utils.py +3 -0
- metadata/ingestion/source/database/iceberg/catalog/__init__.py +65 -0
- metadata/ingestion/source/database/iceberg/catalog/base.py +40 -0
- metadata/ingestion/source/database/iceberg/catalog/dynamodb.py +102 -0
- metadata/ingestion/source/database/iceberg/catalog/glue.py +88 -0
- metadata/ingestion/source/database/iceberg/catalog/hive.py +51 -0
- metadata/ingestion/source/database/iceberg/catalog/rest.py +84 -0
- metadata/ingestion/source/database/iceberg/connection.py +68 -0
- metadata/ingestion/source/database/iceberg/fs/__init__.py +52 -0
- metadata/ingestion/source/database/iceberg/fs/azure.py +44 -0
- metadata/ingestion/source/database/iceberg/fs/base.py +30 -0
- metadata/ingestion/source/database/iceberg/fs/s3.py +77 -0
- metadata/ingestion/source/database/iceberg/helper.py +124 -0
- metadata/ingestion/source/database/iceberg/metadata.py +311 -0
- metadata/ingestion/source/database/iceberg/models.py +66 -0
- metadata/ingestion/source/database/life_cycle_query_mixin.py +72 -3
- metadata/ingestion/source/database/mongodb/connection.py +1 -5
- metadata/ingestion/source/database/mssql/lineage.py +3 -0
- metadata/ingestion/source/database/mssql/metadata.py +108 -4
- metadata/ingestion/source/database/mssql/models.py +30 -0
- metadata/ingestion/source/database/mssql/queries.py +178 -1
- metadata/ingestion/source/database/mssql/usage.py +5 -1
- metadata/ingestion/source/database/mssql/utils.py +207 -4
- metadata/ingestion/source/database/mysql/connection.py +14 -0
- metadata/ingestion/source/database/mysql/metadata.py +0 -2
- metadata/ingestion/source/database/oracle/metadata.py +108 -2
- metadata/ingestion/source/database/oracle/models.py +30 -0
- metadata/ingestion/source/database/oracle/queries.py +99 -18
- metadata/ingestion/source/database/oracle/utils.py +0 -1
- metadata/ingestion/source/database/postgres/connection.py +15 -0
- metadata/ingestion/source/database/postgres/lineage.py +32 -14
- metadata/ingestion/source/database/postgres/metadata.py +15 -7
- metadata/ingestion/source/database/postgres/pgspider/lineage.py +0 -1
- metadata/ingestion/source/database/postgres/queries.py +4 -2
- metadata/ingestion/source/database/postgres/query_parser.py +4 -72
- metadata/ingestion/source/database/postgres/usage.py +41 -0
- metadata/ingestion/source/database/postgres/utils.py +34 -0
- metadata/ingestion/source/database/query_parser_source.py +8 -2
- metadata/ingestion/source/database/redshift/metadata.py +14 -4
- metadata/ingestion/source/database/redshift/queries.py +10 -4
- metadata/ingestion/source/database/redshift/query_parser.py +16 -0
- metadata/ingestion/source/database/redshift/usage.py +0 -2
- metadata/ingestion/source/database/salesforce/metadata.py +32 -3
- metadata/ingestion/source/database/sample_data.py +120 -6
- metadata/ingestion/source/database/sas/client.py +184 -0
- metadata/ingestion/source/database/sas/connection.py +47 -0
- metadata/ingestion/source/database/sas/extension_attr.py +103 -0
- metadata/ingestion/source/database/sas/metadata.py +914 -0
- metadata/ingestion/source/database/snowflake/metadata.py +34 -48
- metadata/ingestion/source/database/snowflake/models.py +6 -1
- metadata/ingestion/source/database/snowflake/queries.py +6 -4
- metadata/ingestion/source/database/snowflake/query_parser.py +5 -20
- metadata/ingestion/source/database/snowflake/utils.py +23 -8
- metadata/ingestion/source/database/stored_procedures_mixin.py +12 -8
- metadata/ingestion/source/database/unitycatalog/__init__.py +0 -0
- metadata/ingestion/source/database/unitycatalog/client.py +87 -0
- metadata/ingestion/source/database/unitycatalog/connection.py +97 -0
- metadata/ingestion/source/database/{databricks/unity_catalog → unitycatalog}/lineage.py +11 -11
- metadata/ingestion/source/database/{databricks/unity_catalog → unitycatalog}/metadata.py +42 -49
- metadata/ingestion/source/database/unitycatalog/query_parser.py +60 -0
- metadata/ingestion/source/database/unitycatalog/usage.py +31 -0
- metadata/ingestion/source/database/usage_source.py +3 -2
- metadata/ingestion/source/messaging/common_broker_source.py +15 -11
- metadata/ingestion/source/messaging/kafka/connection.py +45 -4
- metadata/ingestion/source/messaging/kinesis/metadata.py +6 -3
- metadata/ingestion/source/messaging/messaging_service.py +6 -2
- metadata/ingestion/source/metadata/amundsen/metadata.py +10 -7
- metadata/ingestion/source/metadata/atlas/metadata.py +5 -5
- metadata/ingestion/source/mlmodel/mlflow/metadata.py +5 -2
- metadata/ingestion/source/mlmodel/mlmodel_service.py +6 -2
- metadata/ingestion/source/mlmodel/sagemaker/metadata.py +20 -8
- metadata/ingestion/source/pipeline/airflow/connection.py +0 -12
- metadata/ingestion/source/pipeline/airflow/lineage_parser.py +12 -6
- metadata/ingestion/source/pipeline/airflow/metadata.py +63 -34
- metadata/ingestion/source/pipeline/airflow/models.py +5 -4
- metadata/ingestion/source/pipeline/dagster/metadata.py +7 -4
- metadata/ingestion/source/pipeline/databrickspipeline/connection.py +1 -5
- metadata/ingestion/source/pipeline/databrickspipeline/metadata.py +14 -11
- metadata/ingestion/source/pipeline/domopipeline/metadata.py +7 -4
- metadata/ingestion/source/pipeline/gluepipeline/metadata.py +5 -2
- metadata/ingestion/source/pipeline/pipeline_service.py +6 -2
- metadata/ingestion/source/pipeline/spline/metadata.py +0 -1
- metadata/ingestion/source/search/elasticsearch/connection.py +4 -1
- metadata/ingestion/source/search/elasticsearch/metadata.py +1 -2
- metadata/ingestion/source/search/search_service.py +6 -2
- metadata/ingestion/source/storage/s3/metadata.py +22 -17
- metadata/ingestion/source/storage/storage_service.py +53 -11
- metadata/ingestion/stage/table_usage.py +9 -2
- metadata/mixins/sqalchemy/sqa_mixin.py +14 -7
- metadata/parsers/protobuf_parser.py +29 -11
- metadata/pii/processor.py +9 -2
- metadata/pii/scanners/ner_scanner.py +5 -3
- metadata/profiler/api/models.py +19 -1
- metadata/profiler/interface/pandas/profiler_interface.py +59 -18
- metadata/profiler/interface/profiler_interface.py +14 -4
- metadata/profiler/interface/profiler_interface_factory.py +49 -14
- metadata/profiler/interface/sqlalchemy/bigquery/profiler_interface.py +3 -0
- metadata/profiler/interface/sqlalchemy/databricks/profiler_interface.py +26 -0
- metadata/profiler/interface/sqlalchemy/db2/__init__.py +0 -0
- metadata/profiler/interface/sqlalchemy/db2/profiler_interface.py +38 -0
- metadata/profiler/interface/sqlalchemy/mariadb/profiler_interface.py +85 -0
- metadata/profiler/interface/sqlalchemy/profiler_interface.py +77 -34
- metadata/profiler/interface/sqlalchemy/single_store/profiler_interface.py +2 -2
- metadata/profiler/interface/sqlalchemy/snowflake/profiler_interface.py +7 -0
- metadata/profiler/interface/sqlalchemy/trino/profiler_interface.py +2 -2
- metadata/profiler/interface/sqlalchemy/unity_catalog/profiler_interface.py +33 -0
- metadata/profiler/metrics/composed/null_ratio.py +1 -1
- metadata/profiler/metrics/hybrid/histogram.py +1 -0
- metadata/profiler/metrics/static/max.py +4 -1
- metadata/profiler/metrics/static/min.py +4 -1
- metadata/profiler/metrics/system/queries/snowflake.py +89 -17
- metadata/profiler/metrics/system/system.py +62 -20
- metadata/profiler/orm/functions/conn_test.py +1 -0
- metadata/profiler/orm/functions/length.py +1 -0
- metadata/profiler/orm/functions/median.py +9 -1
- metadata/profiler/orm/functions/sum.py +1 -0
- metadata/profiler/orm/functions/table_metric_computer.py +462 -0
- metadata/profiler/orm/registry.py +2 -0
- metadata/profiler/processor/core.py +129 -62
- metadata/profiler/processor/default.py +14 -3
- metadata/profiler/processor/handle_partition.py +2 -2
- metadata/profiler/processor/processor.py +10 -7
- metadata/profiler/processor/sample_data_handler.py +6 -2
- metadata/profiler/processor/sampler/sqlalchemy/bigquery/sampler.py +31 -3
- metadata/profiler/processor/sampler/sqlalchemy/sampler.py +29 -6
- metadata/profiler/processor/sampler/sqlalchemy/trino/sampler.py +10 -4
- metadata/profiler/source/base/profiler_source.py +5 -2
- metadata/profiler/source/bigquery/type_mapper.py +0 -1
- metadata/profiler/source/databricks/profiler_source.py +36 -0
- metadata/profiler/source/mariadb/functions/median.py +20 -0
- metadata/profiler/source/mariadb/metrics/window/first_quartile.py +10 -0
- metadata/profiler/source/mariadb/metrics/window/median.py +10 -0
- metadata/profiler/source/mariadb/metrics/window/third_quartile.py +10 -0
- metadata/profiler/source/metadata.py +49 -10
- metadata/profiler/source/metadata_ext.py +16 -50
- metadata/profiler/source/profiler_source_factory.py +8 -0
- metadata/py.typed +0 -0
- metadata/readers/dataframe/json.py +5 -4
- metadata/readers/file/api_reader.py +0 -1
- metadata/utils/constants.py +5 -0
- metadata/utils/credentials.py +36 -19
- metadata/utils/datalake/datalake_utils.py +369 -129
- metadata/utils/entity_link.py +26 -6
- metadata/utils/execution_time_tracker.py +199 -0
- metadata/utils/filters.py +4 -0
- metadata/utils/fqn.py +20 -0
- metadata/utils/helpers.py +34 -39
- metadata/utils/importer.py +2 -3
- metadata/utils/life_cycle_utils.py +4 -4
- metadata/utils/logger.py +13 -2
- metadata/utils/partition.py +10 -5
- metadata/utils/secrets/aws_based_secrets_manager.py +67 -4
- metadata/utils/secrets/aws_secrets_manager.py +7 -2
- metadata/utils/secrets/aws_ssm_secrets_manager.py +7 -2
- metadata/utils/secrets/azure_kv_secrets_manager.py +132 -0
- metadata/utils/secrets/{noop_secrets_manager.py → db_secrets_manager.py} +4 -3
- metadata/utils/secrets/external_secrets_manager.py +25 -3
- metadata/utils/secrets/secrets_manager_factory.py +15 -33
- metadata/utils/{source_hash_utils.py → source_hash.py} +10 -1
- metadata/utils/sqlalchemy_utils.py +21 -0
- metadata/utils/storage_metadata_config.py +42 -14
- metadata/utils/tag_utils.py +5 -2
- metadata/workflow/application.py +154 -0
- metadata/workflow/application_output_handler.py +34 -0
- metadata/workflow/base.py +88 -153
- metadata/workflow/data_insight.py +8 -7
- metadata/workflow/data_quality.py +3 -2
- metadata/workflow/ingestion.py +203 -0
- metadata/workflow/metadata.py +2 -3
- metadata/workflow/output_handler.py +226 -0
- metadata/workflow/profiler.py +2 -2
- metadata/workflow/usage.py +3 -4
- metadata/workflow/workflow_output_handler.py +15 -255
- metadata/workflow/workflow_status_mixin.py +44 -52
- openmetadata_ingestion-1.3.2.0rc1.dist-info/METADATA +758 -0
- {openmetadata_ingestion-1.2.4.0.dist-info → openmetadata_ingestion-1.3.2.0rc1.dist-info}/RECORD +870 -762
- {openmetadata_ingestion-1.2.4.0.dist-info → openmetadata_ingestion-1.3.2.0rc1.dist-info}/WHEEL +1 -1
- metadata/generated/schema/entity/applications/appConfig.py +0 -21
- metadata/generated/schema/entity/applications/configuration/dataInsightsApp.py +0 -17
- metadata/generated/schema/entity/applications/configuration/externalAppIngestionConfig.py +0 -38
- metadata/generated/schema/entity/services/connections/database/mongoDB/mongoDBValues.py +0 -44
- metadata/generated/schema/events/dataInsightAlertConfig.py +0 -17
- metadata/generated/schema/events/entitySpelFilters.py +0 -19
- metadata/ingestion/models/es_documents.py +0 -339
- metadata/ingestion/ometa/mixins/glossary_mixin.py +0 -501
- metadata/ingestion/ometa/provider_registry.py +0 -144
- metadata/ingestion/source/database/databricks/legacy/lineage.py +0 -51
- metadata/ingestion/source/database/databricks/legacy/metadata.py +0 -339
- metadata/ingestion/source/metadata/metadata_elasticsearch/metadata.py +0 -144
- metadata/profiler/orm/functions/table_metric_construct.py +0 -365
- metadata/utils/secrets/client/loader.py +0 -78
- openmetadata_ingestion-1.2.4.0.dist-info/METADATA +0 -429
- /metadata/examples/workflows/{datalake_azure.yaml → datalake_azure_client_secret.yaml} +0 -0
- /metadata/ingestion/source/{database/databricks/legacy → dashboard/mstr}/__init__.py +0 -0
- /metadata/ingestion/source/database/{databricks/unity_catalog → bigtable}/__init__.py +0 -0
- /metadata/ingestion/source/{metadata/metadata_elasticsearch → database/doris}/__init__.py +0 -0
- /metadata/{utils/secrets/client → ingestion/source/database/sas}/__init__.py +0 -0
- /metadata/ingestion/source/database/{databricks → unitycatalog}/models.py +0 -0
- {openmetadata_ingestion-1.2.4.0.dist-info → openmetadata_ingestion-1.3.2.0rc1.dist-info}/LICENSE +0 -0
- {openmetadata_ingestion-1.2.4.0.dist-info → openmetadata_ingestion-1.3.2.0rc1.dist-info}/entry_points.txt +0 -0
- {openmetadata_ingestion-1.2.4.0.dist-info → openmetadata_ingestion-1.3.2.0rc1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# Copyright 2024 Collate
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
7
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
8
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
9
|
+
# See the License for the specific language governing permissions and
|
|
10
|
+
# limitations under the License.
|
|
11
|
+
"""
|
|
12
|
+
Bigtable source methods.
|
|
13
|
+
"""
|
|
14
|
+
import traceback
|
|
15
|
+
from typing import Dict, Iterable, List, Optional, Union
|
|
16
|
+
|
|
17
|
+
from google.cloud.bigtable import row_filters
|
|
18
|
+
from google.cloud.bigtable.instance import Instance
|
|
19
|
+
from google.cloud.bigtable.table import Table
|
|
20
|
+
|
|
21
|
+
from metadata.generated.schema.entity.data.table import (
|
|
22
|
+
ConstraintType,
|
|
23
|
+
TableConstraint,
|
|
24
|
+
TableType,
|
|
25
|
+
)
|
|
26
|
+
from metadata.generated.schema.entity.services.connections.database.bigTableConnection import (
|
|
27
|
+
BigTableConnection,
|
|
28
|
+
)
|
|
29
|
+
from metadata.generated.schema.metadataIngestion.workflow import (
|
|
30
|
+
Source as WorkflowSource,
|
|
31
|
+
)
|
|
32
|
+
from metadata.ingestion.api.steps import InvalidSourceException
|
|
33
|
+
from metadata.ingestion.ometa.ometa_api import OpenMetadata
|
|
34
|
+
from metadata.ingestion.source.database.bigtable.client import MultiProjectClient
|
|
35
|
+
from metadata.ingestion.source.database.bigtable.models import Row
|
|
36
|
+
from metadata.ingestion.source.database.common_nosql_source import (
|
|
37
|
+
SAMPLE_SIZE as GLOBAL_SAMPLE_SIZE,
|
|
38
|
+
)
|
|
39
|
+
from metadata.ingestion.source.database.common_nosql_source import CommonNoSQLSource
|
|
40
|
+
from metadata.ingestion.source.database.multi_db_source import MultiDBSource
|
|
41
|
+
from metadata.utils.logger import ingestion_logger
|
|
42
|
+
|
|
43
|
+
logger = ingestion_logger()
|
|
44
|
+
|
|
45
|
+
# BigTable group's its columns in column families. We make an assumption that if the table has a big number of
|
|
46
|
+
# columns, we at least get a sample of the first 100 column families.
|
|
47
|
+
MAX_COLUMN_FAMILIES = 100
|
|
48
|
+
SAMPLES_PER_COLUMN_FAMILY = 100
|
|
49
|
+
|
|
50
|
+
ProjectId = str
|
|
51
|
+
InstanceId = str
|
|
52
|
+
TableId = str
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class BigtableSource(CommonNoSQLSource, MultiDBSource):
|
|
56
|
+
"""
|
|
57
|
+
Implements the necessary methods to extract database metadata from Google BigTable Source.
|
|
58
|
+
BigTable is a NoSQL database service for handling large amounts of data. Tha mapping is as follows:
|
|
59
|
+
project -> instance -> table -> column_family.column
|
|
60
|
+
(database) (schema)
|
|
61
|
+
For more infor about BigTable: https://cloud.google.com/bigtable/?hl=en
|
|
62
|
+
All data types are registered as bytes.
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
def __init__(self, config: WorkflowSource, metadata: OpenMetadata):
|
|
66
|
+
super().__init__(config, metadata)
|
|
67
|
+
self.client: MultiProjectClient = self.connection_obj
|
|
68
|
+
|
|
69
|
+
# ths instances and tables are cached to avoid making redundant requests to the API.
|
|
70
|
+
self.instances: Dict[ProjectId, Dict[InstanceId, Instance]] = {}
|
|
71
|
+
self.tables: Dict[ProjectId, Dict[InstanceId, Dict[TableId, Table]]] = {}
|
|
72
|
+
|
|
73
|
+
@classmethod
|
|
74
|
+
def create(cls, config_dict, metadata: OpenMetadata):
|
|
75
|
+
config: WorkflowSource = WorkflowSource.parse_obj(config_dict)
|
|
76
|
+
connection: BigTableConnection = config.serviceConnection.__root__.config
|
|
77
|
+
if not isinstance(connection, BigTableConnection):
|
|
78
|
+
raise InvalidSourceException(
|
|
79
|
+
f"Expected BigTableConnection, but got {connection}"
|
|
80
|
+
)
|
|
81
|
+
return cls(config, metadata)
|
|
82
|
+
|
|
83
|
+
def get_configured_database(self) -> Optional[str]:
|
|
84
|
+
"""
|
|
85
|
+
This connector uses "virtual databases" in the form of GCP projects.
|
|
86
|
+
The concept of a default project for the GCP client is not useful here because the project ID
|
|
87
|
+
is always an explicit part of the connection. Therefore, this method returns None and the databases
|
|
88
|
+
are resolved using `self.get_database_names`.
|
|
89
|
+
"""
|
|
90
|
+
return None
|
|
91
|
+
|
|
92
|
+
def get_database_names(self) -> Iterable[str]:
|
|
93
|
+
return self.get_database_names_raw()
|
|
94
|
+
|
|
95
|
+
def get_database_names_raw(self) -> Iterable[str]:
|
|
96
|
+
yield from self.client.project_ids()
|
|
97
|
+
|
|
98
|
+
def get_schema_name_list(self) -> List[str]:
|
|
99
|
+
project_id = self.context.database
|
|
100
|
+
try:
|
|
101
|
+
# the first element is a list of instances
|
|
102
|
+
# the second element is another collection (seems empty) and I do not know what is its purpose
|
|
103
|
+
instances, _ = self.client.list_instances(project_id=project_id)
|
|
104
|
+
self.instances[project_id] = {
|
|
105
|
+
instance.instance_id: instance for instance in instances
|
|
106
|
+
}
|
|
107
|
+
return list(self.instances[project_id].keys())
|
|
108
|
+
except Exception as err:
|
|
109
|
+
logger.debug(traceback.format_exc())
|
|
110
|
+
logger.error(
|
|
111
|
+
f"Failed to list BigTable instances in project {project_id}: {err}"
|
|
112
|
+
)
|
|
113
|
+
raise
|
|
114
|
+
|
|
115
|
+
def get_table_name_list(self, schema_name: str) -> List[str]:
|
|
116
|
+
project_id = self.context.database
|
|
117
|
+
try:
|
|
118
|
+
instance = self._get_instance(project_id, schema_name)
|
|
119
|
+
if instance is None:
|
|
120
|
+
raise RuntimeError(f"Instance {project_id}/{schema_name} not found.")
|
|
121
|
+
tables = instance.list_tables()
|
|
122
|
+
for table in tables:
|
|
123
|
+
self._set_nested(
|
|
124
|
+
self.tables,
|
|
125
|
+
[project_id, instance.instance_id, table.table_id],
|
|
126
|
+
table,
|
|
127
|
+
)
|
|
128
|
+
return list(self.tables[project_id][schema_name].keys())
|
|
129
|
+
except Exception as err:
|
|
130
|
+
logger.debug(traceback.format_exc())
|
|
131
|
+
# add context to the error message
|
|
132
|
+
logger.error(
|
|
133
|
+
f"Failed to list BigTable table names in {project_id}.{schema_name}: {err}"
|
|
134
|
+
)
|
|
135
|
+
return []
|
|
136
|
+
|
|
137
|
+
def get_table_constraints(
|
|
138
|
+
self, db_name: str, schema_name: str, table_name: str
|
|
139
|
+
) -> List[TableConstraint]:
|
|
140
|
+
return [
|
|
141
|
+
TableConstraint(
|
|
142
|
+
constraintType=ConstraintType.PRIMARY_KEY, columns=["row_key"]
|
|
143
|
+
)
|
|
144
|
+
]
|
|
145
|
+
|
|
146
|
+
def get_table_columns_dict(
|
|
147
|
+
self, schema_name: str, table_name: str
|
|
148
|
+
) -> Union[List[Dict], Dict]:
|
|
149
|
+
project_id = self.context.database
|
|
150
|
+
try:
|
|
151
|
+
table = self._get_table(project_id, schema_name, table_name)
|
|
152
|
+
if table is None:
|
|
153
|
+
raise RuntimeError(
|
|
154
|
+
f"Table {project_id}/{schema_name}/{table_name} not found."
|
|
155
|
+
)
|
|
156
|
+
column_families = table.list_column_families()
|
|
157
|
+
# all BigTable tables have a "row_key" column. Even if there are no records in the table.
|
|
158
|
+
records = [{"row_key": b"row_key"}]
|
|
159
|
+
# In order to get a "good" sample of data, we try to distribute the sampling
|
|
160
|
+
# across multiple column families.
|
|
161
|
+
for column_family in list(column_families.keys())[:MAX_COLUMN_FAMILIES]:
|
|
162
|
+
records.extend(
|
|
163
|
+
self._get_records_for_column_family(
|
|
164
|
+
table, column_family, SAMPLES_PER_COLUMN_FAMILY
|
|
165
|
+
)
|
|
166
|
+
)
|
|
167
|
+
if len(records) >= GLOBAL_SAMPLE_SIZE:
|
|
168
|
+
break
|
|
169
|
+
return records
|
|
170
|
+
except Exception as err:
|
|
171
|
+
logger.debug(traceback.format_exc())
|
|
172
|
+
logger.warning(
|
|
173
|
+
f"Failed to read BigTable rows for [{project_id}.{schema_name}.{table_name}]: {err}"
|
|
174
|
+
)
|
|
175
|
+
return []
|
|
176
|
+
|
|
177
|
+
def get_source_url(
|
|
178
|
+
self,
|
|
179
|
+
database_name: Optional[str] = None,
|
|
180
|
+
schema_name: Optional[str] = None,
|
|
181
|
+
table_name: Optional[str] = None,
|
|
182
|
+
table_type: Optional[TableType] = None,
|
|
183
|
+
) -> Optional[str]:
|
|
184
|
+
"""
|
|
185
|
+
Method to get the source url for a BigTable table
|
|
186
|
+
"""
|
|
187
|
+
try:
|
|
188
|
+
if schema_name and table_name:
|
|
189
|
+
return (
|
|
190
|
+
"https://console.cloud.google.com/bigtable/instances/"
|
|
191
|
+
f"{schema_name}/tables/{table_name}/overview?project={database_name}"
|
|
192
|
+
)
|
|
193
|
+
except Exception as exc:
|
|
194
|
+
logger.debug(traceback.format_exc())
|
|
195
|
+
logger.error(f"Unable to get source url: {exc}")
|
|
196
|
+
return None
|
|
197
|
+
|
|
198
|
+
@staticmethod
|
|
199
|
+
def _set_nested(dct: dict, keys: List[str], value: any) -> None:
|
|
200
|
+
for key in keys[:-1]:
|
|
201
|
+
dct = dct.setdefault(key, {})
|
|
202
|
+
dct[keys[-1]] = value
|
|
203
|
+
|
|
204
|
+
@staticmethod
|
|
205
|
+
def _get_records_for_column_family(
|
|
206
|
+
table: Table, column_family: str, limit: int
|
|
207
|
+
) -> List[Dict]:
|
|
208
|
+
filter_ = row_filters.ColumnRangeFilter(column_family_id=column_family)
|
|
209
|
+
rows = table.read_rows(limit=limit, filter_=filter_)
|
|
210
|
+
return [Row.from_partial_row(row).to_record() for row in rows]
|
|
211
|
+
|
|
212
|
+
def _get_table(
|
|
213
|
+
self, project_id: str, schema_name: str, table_name: str
|
|
214
|
+
) -> Optional[Table]:
|
|
215
|
+
try:
|
|
216
|
+
return self.tables[project_id][schema_name][table_name]
|
|
217
|
+
except KeyError:
|
|
218
|
+
return None
|
|
219
|
+
|
|
220
|
+
def _get_instance(self, project_id: str, schema_name: str) -> Optional[Instance]:
|
|
221
|
+
try:
|
|
222
|
+
return self.instances[project_id][schema_name]
|
|
223
|
+
except KeyError:
|
|
224
|
+
return None
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Copyright 2024 Collate
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
7
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
8
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
9
|
+
# See the License for the specific language governing permissions and
|
|
10
|
+
# limitations under the License.
|
|
11
|
+
"""
|
|
12
|
+
Bigtable source models.
|
|
13
|
+
"""
|
|
14
|
+
from typing import Dict, List
|
|
15
|
+
|
|
16
|
+
from google.cloud.bigtable.row import PartialRowData
|
|
17
|
+
from pydantic import BaseModel
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class Value(BaseModel):
|
|
21
|
+
"""A Bigtable cell value."""
|
|
22
|
+
|
|
23
|
+
timestamp: int
|
|
24
|
+
value: bytes
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class Cell(BaseModel):
|
|
28
|
+
"""A Bigtable cell."""
|
|
29
|
+
|
|
30
|
+
values: List[Value]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class Row(BaseModel):
|
|
34
|
+
"""A Bigtable row."""
|
|
35
|
+
|
|
36
|
+
cells: Dict[str, Dict[bytes, Cell]]
|
|
37
|
+
row_key: bytes
|
|
38
|
+
|
|
39
|
+
@classmethod
|
|
40
|
+
def from_partial_row(cls, row: PartialRowData):
|
|
41
|
+
cells = {}
|
|
42
|
+
for column_family, cf_cells in row.cells.items():
|
|
43
|
+
cells.setdefault(column_family, {})
|
|
44
|
+
for column, cell in cf_cells.items():
|
|
45
|
+
cells[column_family][column] = Cell(
|
|
46
|
+
values=[Value(timestamp=c.timestamp, value=c.value) for c in cell]
|
|
47
|
+
)
|
|
48
|
+
return cls(cells=cells, row_key=row.row_key)
|
|
49
|
+
|
|
50
|
+
def to_record(self) -> Dict[str, bytes]:
|
|
51
|
+
record = {}
|
|
52
|
+
for column_family, cells in self.cells.items():
|
|
53
|
+
for column, cell in cells.items():
|
|
54
|
+
# Since each cell can have multiple values and the API returns them in descending order
|
|
55
|
+
# from latest to oldest, we only take the latest value. This probably does not matter since
|
|
56
|
+
# all we care about is data types and all data stored in BigTable is of type `bytes`.
|
|
57
|
+
record[f"{column_family}.{column.decode()}"] = cell.values[0].value
|
|
58
|
+
record["row_key"] = self.row_key
|
|
59
|
+
|
|
60
|
+
return record
|
|
@@ -14,16 +14,6 @@ their raw information from the source
|
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
def remove_table_from_column_name(table_name: str, raw_column_name: str) -> str:
|
|
18
|
-
"""
|
|
19
|
-
Given a column `table.column`, return only `column`.
|
|
20
|
-
|
|
21
|
-
Note that we might have columns which have real dots
|
|
22
|
-
"." in the name, so we cannot just split.
|
|
23
|
-
"""
|
|
24
|
-
return raw_column_name.replace(table_name + ".", "")
|
|
25
|
-
|
|
26
|
-
|
|
27
17
|
def truncate_column_name(col_name: str):
|
|
28
18
|
"""
|
|
29
19
|
OpenMetadata table column specification limits column name to 128 characters.
|
|
@@ -369,7 +369,9 @@ class ColumnTypeParser:
|
|
|
369
369
|
|
|
370
370
|
@staticmethod
|
|
371
371
|
def _parse_struct_fields_string(stuct_type: str) -> Dict[str, object]:
|
|
372
|
-
parts = ColumnTypeParser._ignore_brackets_split(
|
|
372
|
+
parts = ColumnTypeParser._ignore_brackets_split(
|
|
373
|
+
stuct_type, ",", skip_no_child_validation=True
|
|
374
|
+
)
|
|
373
375
|
columns = []
|
|
374
376
|
for part in parts:
|
|
375
377
|
name_and_type = ColumnTypeParser._ignore_brackets_split(part, ":")
|
|
@@ -387,9 +389,10 @@ class ColumnTypeParser:
|
|
|
387
389
|
field_type = ColumnTypeParser._parse_datatype_string(name_and_type[1])
|
|
388
390
|
field_type["name"] = field_name
|
|
389
391
|
columns.append(field_type)
|
|
392
|
+
|
|
390
393
|
return {
|
|
391
394
|
"children": columns,
|
|
392
|
-
"dataTypeDisplay": f"struct<{stuct_type}>",
|
|
395
|
+
"dataTypeDisplay": f"struct<{stuct_type or 'unknown'}>",
|
|
393
396
|
"dataType": "STRUCT",
|
|
394
397
|
}
|
|
395
398
|
|
|
@@ -431,7 +434,9 @@ class ColumnTypeParser:
|
|
|
431
434
|
}
|
|
432
435
|
|
|
433
436
|
@staticmethod
|
|
434
|
-
def _ignore_brackets_split(
|
|
437
|
+
def _ignore_brackets_split(
|
|
438
|
+
string: str, separator: str, skip_no_child_validation: bool = False
|
|
439
|
+
) -> List[str]:
|
|
435
440
|
parts = []
|
|
436
441
|
buf = ""
|
|
437
442
|
level = 0
|
|
@@ -452,9 +457,10 @@ class ColumnTypeParser:
|
|
|
452
457
|
else:
|
|
453
458
|
buf += char
|
|
454
459
|
|
|
455
|
-
if len(buf) == 0:
|
|
460
|
+
if len(buf) == 0 and not skip_no_child_validation:
|
|
456
461
|
raise ValueError(f"The {separator} cannot be the last char: {string}")
|
|
457
|
-
|
|
462
|
+
if buf:
|
|
463
|
+
parts.append(buf)
|
|
458
464
|
return parts
|
|
459
465
|
|
|
460
466
|
@staticmethod
|
|
@@ -41,13 +41,16 @@ from metadata.generated.schema.entity.data.table import (
|
|
|
41
41
|
TablePartition,
|
|
42
42
|
TableType,
|
|
43
43
|
)
|
|
44
|
+
from metadata.generated.schema.entity.services.ingestionPipelines.status import (
|
|
45
|
+
StackTraceError,
|
|
46
|
+
)
|
|
44
47
|
from metadata.generated.schema.metadataIngestion.databaseServiceMetadataPipeline import (
|
|
45
48
|
DatabaseServiceMetadataPipeline,
|
|
46
49
|
)
|
|
47
50
|
from metadata.generated.schema.metadataIngestion.workflow import (
|
|
48
51
|
Source as WorkflowSource,
|
|
49
52
|
)
|
|
50
|
-
from metadata.ingestion.api.models import Either
|
|
53
|
+
from metadata.ingestion.api.models import Either
|
|
51
54
|
from metadata.ingestion.lineage.sql_lineage import get_column_fqn
|
|
52
55
|
from metadata.ingestion.models.ometa_classification import OMetaTagAndClassification
|
|
53
56
|
from metadata.ingestion.ometa.ometa_api import OpenMetadata
|
|
@@ -59,8 +62,8 @@ from metadata.ingestion.source.database.stored_procedures_mixin import QueryByPr
|
|
|
59
62
|
from metadata.ingestion.source.models import TableView
|
|
60
63
|
from metadata.utils import fqn
|
|
61
64
|
from metadata.utils.db_utils import get_view_lineage
|
|
65
|
+
from metadata.utils.execution_time_tracker import calculate_execution_time_generator
|
|
62
66
|
from metadata.utils.filters import filter_by_table
|
|
63
|
-
from metadata.utils.helpers import calculate_execution_time_generator
|
|
64
67
|
from metadata.utils.logger import ingestion_logger
|
|
65
68
|
|
|
66
69
|
logger = ingestion_logger()
|
|
@@ -171,6 +174,7 @@ class CommonDbSourceService(
|
|
|
171
174
|
service=self.context.database_service,
|
|
172
175
|
description=self.get_database_description(database_name),
|
|
173
176
|
sourceUrl=self.get_source_url(database_name=database_name),
|
|
177
|
+
tags=self.get_database_tag_labels(database_name=database_name),
|
|
174
178
|
)
|
|
175
179
|
)
|
|
176
180
|
|
|
@@ -209,6 +213,7 @@ class CommonDbSourceService(
|
|
|
209
213
|
database_name=self.context.database,
|
|
210
214
|
schema_name=schema_name,
|
|
211
215
|
),
|
|
216
|
+
tags=self.get_schema_tag_labels(schema_name=schema_name),
|
|
212
217
|
)
|
|
213
218
|
)
|
|
214
219
|
|
|
@@ -246,6 +251,23 @@ class CommonDbSourceService(
|
|
|
246
251
|
for table_name in self.inspector.get_table_names(schema_name) or []
|
|
247
252
|
]
|
|
248
253
|
|
|
254
|
+
def query_view_names_and_types(
|
|
255
|
+
self, schema_name: str
|
|
256
|
+
) -> Iterable[TableNameAndType]:
|
|
257
|
+
"""
|
|
258
|
+
Connect to the source database to get the view
|
|
259
|
+
name and type. By default, use the inspector method
|
|
260
|
+
to get the names and pass the View type.
|
|
261
|
+
|
|
262
|
+
This is useful for sources where we need fine-grained
|
|
263
|
+
logic on how to handle table types, e.g., material views,...
|
|
264
|
+
"""
|
|
265
|
+
|
|
266
|
+
return [
|
|
267
|
+
TableNameAndType(name=table_name, type_=TableType.View)
|
|
268
|
+
for table_name in self.inspector.get_view_names(schema_name) or []
|
|
269
|
+
]
|
|
270
|
+
|
|
249
271
|
def get_tables_name_and_type(self) -> Optional[Iterable[Tuple[str, str]]]:
|
|
250
272
|
"""
|
|
251
273
|
Handle table and views.
|
|
@@ -285,8 +307,10 @@ class CommonDbSourceService(
|
|
|
285
307
|
yield table_name, table_and_type.type_
|
|
286
308
|
|
|
287
309
|
if self.source_config.includeViews:
|
|
288
|
-
for
|
|
289
|
-
view_name = self.standardize_table_name(
|
|
310
|
+
for view_and_type in self.query_view_names_and_types(schema_name):
|
|
311
|
+
view_name = self.standardize_table_name(
|
|
312
|
+
schema_name, view_and_type.name
|
|
313
|
+
)
|
|
290
314
|
view_fqn = fqn.build(
|
|
291
315
|
self.metadata,
|
|
292
316
|
entity_type=Table,
|
|
@@ -307,7 +331,7 @@ class CommonDbSourceService(
|
|
|
307
331
|
"Table Filtered Out",
|
|
308
332
|
)
|
|
309
333
|
continue
|
|
310
|
-
yield view_name,
|
|
334
|
+
yield view_name, view_and_type.type_
|
|
311
335
|
except Exception as err:
|
|
312
336
|
logger.warning(
|
|
313
337
|
f"Fetching tables names failed for schema {schema_name} due to - {err}"
|
|
@@ -317,7 +341,7 @@ class CommonDbSourceService(
|
|
|
317
341
|
def get_view_definition(
|
|
318
342
|
self, table_type: str, table_name: str, schema_name: str, inspector: Inspector
|
|
319
343
|
) -> Optional[str]:
|
|
320
|
-
if table_type
|
|
344
|
+
if table_type in (TableType.View, TableType.MaterializedView):
|
|
321
345
|
try:
|
|
322
346
|
view_definition = inspector.get_view_definition(table_name, schema_name)
|
|
323
347
|
view_definition = (
|
|
@@ -381,7 +405,7 @@ class CommonDbSourceService(
|
|
|
381
405
|
"""Not Implemented"""
|
|
382
406
|
yield from []
|
|
383
407
|
|
|
384
|
-
@calculate_execution_time_generator
|
|
408
|
+
@calculate_execution_time_generator(store=False)
|
|
385
409
|
def yield_table(
|
|
386
410
|
self, table_name_and_type: Tuple[str, str]
|
|
387
411
|
) -> Iterable[Either[CreateTableRequest]]:
|
|
@@ -439,6 +463,7 @@ class CommonDbSourceService(
|
|
|
439
463
|
database_name=self.context.database,
|
|
440
464
|
table_type=table_type,
|
|
441
465
|
),
|
|
466
|
+
owner=self.get_owner_ref(table_name=table_name),
|
|
442
467
|
)
|
|
443
468
|
|
|
444
469
|
is_partitioned, partition_details = self.get_table_partition_details(
|
|
@@ -469,7 +494,7 @@ class CommonDbSourceService(
|
|
|
469
494
|
error = f"Unexpected exception to yield table [{table_name}]: {exc}"
|
|
470
495
|
yield Either(
|
|
471
496
|
left=StackTraceError(
|
|
472
|
-
name=table_name, error=error,
|
|
497
|
+
name=table_name, error=error, stackTrace=traceback.format_exc()
|
|
473
498
|
)
|
|
474
499
|
)
|
|
475
500
|
|
|
@@ -28,14 +28,21 @@ from metadata.generated.schema.api.data.createTable import CreateTableRequest
|
|
|
28
28
|
from metadata.generated.schema.api.lineage.addLineage import AddLineageRequest
|
|
29
29
|
from metadata.generated.schema.entity.data.database import Database
|
|
30
30
|
from metadata.generated.schema.entity.data.databaseSchema import DatabaseSchema
|
|
31
|
-
from metadata.generated.schema.entity.data.table import
|
|
31
|
+
from metadata.generated.schema.entity.data.table import (
|
|
32
|
+
Table,
|
|
33
|
+
TableConstraint,
|
|
34
|
+
TableType,
|
|
35
|
+
)
|
|
36
|
+
from metadata.generated.schema.entity.services.ingestionPipelines.status import (
|
|
37
|
+
StackTraceError,
|
|
38
|
+
)
|
|
32
39
|
from metadata.generated.schema.metadataIngestion.databaseServiceMetadataPipeline import (
|
|
33
40
|
DatabaseServiceMetadataPipeline,
|
|
34
41
|
)
|
|
35
42
|
from metadata.generated.schema.metadataIngestion.workflow import (
|
|
36
43
|
Source as WorkflowSource,
|
|
37
44
|
)
|
|
38
|
-
from metadata.ingestion.api.models import Either
|
|
45
|
+
from metadata.ingestion.api.models import Either
|
|
39
46
|
from metadata.ingestion.models.ometa_classification import OMetaTagAndClassification
|
|
40
47
|
from metadata.ingestion.ometa.ometa_api import OpenMetadata
|
|
41
48
|
from metadata.ingestion.source.connections import get_connection
|
|
@@ -43,7 +50,7 @@ from metadata.ingestion.source.database.database_service import DatabaseServiceS
|
|
|
43
50
|
from metadata.ingestion.source.database.stored_procedures_mixin import QueryByProcedure
|
|
44
51
|
from metadata.utils import fqn
|
|
45
52
|
from metadata.utils.constants import DEFAULT_DATABASE
|
|
46
|
-
from metadata.utils.datalake.datalake_utils import
|
|
53
|
+
from metadata.utils.datalake.datalake_utils import DataFrameColumnParser
|
|
47
54
|
from metadata.utils.filters import filter_by_schema, filter_by_table
|
|
48
55
|
from metadata.utils.logger import ingestion_logger
|
|
49
56
|
|
|
@@ -200,6 +207,15 @@ class CommonNoSQLSource(DatabaseServiceSource, ABC):
|
|
|
200
207
|
need to be overridden by sources
|
|
201
208
|
"""
|
|
202
209
|
|
|
210
|
+
def get_table_constraints(
|
|
211
|
+
self,
|
|
212
|
+
db_name: str,
|
|
213
|
+
schema_name: str,
|
|
214
|
+
table_name: str,
|
|
215
|
+
) -> Optional[List[TableConstraint]]:
|
|
216
|
+
# pylint: disable=unused-argument
|
|
217
|
+
return None
|
|
218
|
+
|
|
203
219
|
def yield_table(
|
|
204
220
|
self, table_name_and_type: Tuple[str, str]
|
|
205
221
|
) -> Iterable[Either[CreateTableRequest]]:
|
|
@@ -214,12 +230,17 @@ class CommonNoSQLSource(DatabaseServiceSource, ABC):
|
|
|
214
230
|
try:
|
|
215
231
|
data = self.get_table_columns_dict(schema_name, table_name)
|
|
216
232
|
df = pd.DataFrame.from_records(list(data))
|
|
217
|
-
|
|
233
|
+
column_parser = DataFrameColumnParser.create(df)
|
|
234
|
+
columns = column_parser.get_columns()
|
|
218
235
|
table_request = CreateTableRequest(
|
|
219
236
|
name=table_name,
|
|
220
237
|
tableType=table_type,
|
|
221
238
|
columns=columns,
|
|
222
|
-
tableConstraints=
|
|
239
|
+
tableConstraints=self.get_table_constraints(
|
|
240
|
+
schema_name=schema_name,
|
|
241
|
+
table_name=table_name,
|
|
242
|
+
db_name=self.context.database,
|
|
243
|
+
),
|
|
223
244
|
databaseSchema=fqn.build(
|
|
224
245
|
metadata=self.metadata,
|
|
225
246
|
entity_type=DatabaseSchema,
|
|
@@ -242,7 +263,7 @@ class CommonNoSQLSource(DatabaseServiceSource, ABC):
|
|
|
242
263
|
left=StackTraceError(
|
|
243
264
|
name=table_name,
|
|
244
265
|
error=f"Unexpected exception to yield table [{table_name}]: {exc}",
|
|
245
|
-
|
|
266
|
+
stackTrace=traceback.format_exc(),
|
|
246
267
|
)
|
|
247
268
|
)
|
|
248
269
|
|