Skip to content

Commit bfab1fd

Browse files
authored
Merge pull request #123 from oracle/dev/1.7.0
v1.7.0
2 parents 745b53f + 6e5f6db commit bfab1fd

32 files changed

+741
-96
lines changed

.github/workflows/oracle-xe-adapter-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ jobs:
4848
- name: Install dbt-oracle with core dependencies
4949
run: |
5050
python -m pip install --upgrade pip
51-
pip install pytest 'dbt-tests-adapter~=1.6,<1.7'
51+
pip install pytest 'dbt-tests-adapter~=1.7,<1.8'
5252
pip install -r requirements.txt
5353
pip install -e .
5454

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,4 +147,6 @@ doc/build.gitbak
147147
.venv1.4/
148148
.venv1.5/
149149
.venv1.6/
150+
.venv1.7/
151+
.venv*/
150152
dbt_adbs_py_test_project

Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Configuration variables
2-
VERSION=1.6.1
2+
VERSION=1.7.0
33
PROJ_DIR?=$(shell pwd)
44
VENV_DIR?=${PROJ_DIR}/.bldenv
55
BUILD_DIR=${PROJ_DIR}/build
@@ -36,6 +36,7 @@ adbs_local_env_test: wheel clean_venv
3636
cd dbt_adbs_test_project && ${VENV_DIR}/bin/dbt run --profiles-dir ./
3737
cd dbt_adbs_test_project && ${VENV_DIR}/bin/dbt snapshot --profiles-dir ./
3838
cd dbt_adbs_test_project && ${VENV_DIR}/bin/dbt snapshot --profiles-dir ./
39+
cd dbt_adbs_test_project && ${VENV_DIR}/bin/dbt show --limit 4 --select people --profiles-dir ./
3940
cd dbt_adbs_test_project && ${VENV_DIR}/bin/dbt docs generate --profiles-dir ./
4041
cd dbt_adbs_test_project && ${VENV_DIR}/bin/dbt run-operation drop_schema --args 'relation: ${DBT_ORACLE_SCHEMA}' --profiles-dir ./
4142
cd dbt_adbs_test_project && ${VENV_DIR}/bin/dbt clean --profiles-dir ./
@@ -57,6 +58,7 @@ adbs_pypi_test: clean_venv
5758
cd dbt_adbs_test_project && ${VENV_DIR}/bin/dbt run --profiles-dir ./
5859
cd dbt_adbs_test_project && ${VENV_DIR}/bin/dbt snapshot --profiles-dir ./
5960
cd dbt_adbs_test_project && ${VENV_DIR}/bin/dbt snapshot --profiles-dir ./
61+
cd dbt_adbs_test_project && ${VENV_DIR}/bin/dbt show --limit 4 --select people --profiles-dir ./
6062
cd dbt_adbs_test_project && ${VENV_DIR}/bin/dbt docs generate --profiles-dir ./
6163
cd dbt_adbs_test_project && ${VENV_DIR}/bin/dbt run-operation drop_schema --args 'relation: ${DBT_ORACLE_SCHEMA}' --profiles-dir ./
6264
cd dbt_adbs_test_project && ${VENV_DIR}/bin/dbt clean --profiles-dir ./

dbt/adapters/oracle/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@
1414
See the License for the specific language governing permissions and
1515
limitations under the License.
1616
"""
17-
version = "1.6.7"
17+
version = "1.7.3"

dbt/adapters/oracle/connection_helper.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,13 @@ class OracleDriverType(str, enum.Enum):
100100
SQLNET_ORA_CONFIG = None
101101

102102
# Set the environment variable ORA_PYTHON_DRIVER_TYPE to one of “cx”, “thin”, or “thick”:
103-
ORA_PYTHON_DRIVER_TYPE = os.getenv('ORA_PYTHON_DRIVER_TYPE', 'cx').upper()
103+
ORA_PYTHON_DRIVER_TYPE = os.getenv('ORA_PYTHON_DRIVER_TYPE', 'thin').upper()
104104
if ORA_PYTHON_DRIVER_TYPE == OracleDriverType.CX_ORACLE:
105105
logger.info("Running in cx mode")
106106
description = (
107107
f"cx_oracle is no longer maintained, use python-oracledb"
108108
f"\n\nTo switch to python-oracledb set the environment variable ORA_PYTHON_DRIVER_TYPE=thin "
109-
f"\n\nDefault value of ORA_PYTHON_DRIVER_TYPE will be switched to thin started with v1.7.0 "
109+
f"\n\nStarting with dbt-oracle version 1.7, default value of ORA_PYTHON_DRIVER_TYPE is thin"
110110
f"\n\nRead the guideline here: "
111111
f"https://docs.getdbt.com/reference/warehouse-setups/oracle-setup#configure-the-python-driver-mode"
112112
f"\n\nDocumentation for python-oracledb can be found here: "

dbt/adapters/oracle/connections.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,12 @@ class OracleAdapterCredentials(Credentials):
8282
of parameters profiled in the profile.
8383
"""
8484
# Mandatory required arguments.
85-
user: str
86-
password: str
85+
user: Optional[str] = None
86+
password: Optional[str] = None
87+
8788
# Specifying database is optional
88-
database: Optional[str]
89+
database: Optional[str] = None
90+
schema: Optional[str] = None
8991

9092
# OracleConnectionMethod.TNS
9193
tns_name: Optional[str] = None
@@ -212,7 +214,7 @@ def open(cls, connection):
212214
}
213215

214216
if oracledb.__name__ == "oracledb":
215-
conn_config['connection_id_prefix'] = 'dbt-oracle-'
217+
conn_config['connection_id_prefix'] = f'dbt-oracle-{dbt_version}-'
216218

217219
if credentials.shardingkey:
218220
conn_config['shardingkey'] = credentials.shardingkey
@@ -239,7 +241,7 @@ def open(cls, connection):
239241
handle = oracledb.connect(**conn_config)
240242
# client_identifier and module are saved in corresponding columns in v$session
241243
session_info = cls.get_session_info(credentials=credentials)
242-
logger.info(f"Session info :{json.dumps(session_info)}")
244+
logger.debug(f"Session info :{json.dumps(session_info)}")
243245
for k, v in session_info.items():
244246
try:
245247
setattr(handle, k, v)

dbt/adapters/oracle/python_submissions.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
import http
1818
import json
1919
from typing import Dict
20+
import uuid
21+
import platform
2022

2123
import requests
2224
import time
@@ -25,6 +27,7 @@
2527
from dbt.adapters.oracle import OracleAdapterCredentials
2628
from dbt.events import AdapterLogger
2729
from dbt.ui import red, green
30+
from dbt.version import __version__ as dbt_version
2831

2932
# ADB-S OML Rest API minimum timeout is 1800 seconds
3033
DEFAULT_TIMEOUT_IN_SECONDS = 1800
@@ -140,6 +143,20 @@ def __init__(self,
140143
self.oml4py_client = OracleOML4PYClient(oml_cloud_service_url=credential.oml_cloud_service_url,
141144
username=credential.user,
142145
password=credential.password)
146+
self.session_info = self.get_session_info(credentials=credential)
147+
148+
@staticmethod
149+
def get_session_info(credentials):
150+
default_action = "DBT RUN OML4PY"
151+
default_client_identifier = f'dbt-oracle-client-{uuid.uuid4()}'
152+
default_client_info = "_".join([platform.node(), platform.machine()])
153+
default_module = f'dbt-{dbt_version}'
154+
return {
155+
"action": credentials.session_info.get("action", default_action),
156+
"client_identifier": credentials.session_info.get("client_identifier", default_client_identifier),
157+
"clientinfo": credentials.session_info.get("client_info", default_client_info),
158+
"module": credentials.session_info.get("module", default_module)
159+
}
143160

144161
def schedule_async_job_and_wait_for_completion(self, data):
145162
logger.info(f"Running Python aysnc job using {data}")
@@ -196,7 +213,8 @@ def schedule_async_job_and_wait_for_completion(self, data):
196213

197214
def __call__(self, *args, **kwargs):
198215
data = {
199-
"service": self.service
216+
"service": self.service,
217+
"parameters": json.dumps(self.session_info)
200218
}
201219
if self.async_flag:
202220
data["asyncFlag"] = self.async_flag

dbt/include/oracle/macros/adapters.sql

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -300,29 +300,7 @@
300300

301301
{% macro oracle__drop_relation(relation) -%}
302302
{% call statement('drop_relation', auto_begin=False) -%}
303-
DECLARE
304-
dne_942 EXCEPTION;
305-
PRAGMA EXCEPTION_INIT(dne_942, -942);
306-
attempted_ddl_on_in_use_GTT EXCEPTION;
307-
pragma EXCEPTION_INIT(attempted_ddl_on_in_use_GTT, -14452);
308-
mv_dne_12003 EXCEPTION;
309-
PRAGMA EXCEPTION_INIT(mv_dne_12003, -12003);
310-
BEGIN
311-
SAVEPOINT start_transaction;
312-
{%- if relation.is_materialized_view -%}
313-
EXECUTE IMMEDIATE '{{ oracle__drop_materialized_view(relation) }}';
314-
{%- else -%}
315-
EXECUTE IMMEDIATE 'DROP {{ relation.type }} {{ relation }} cascade constraint';
316-
{%- endif -%}
317-
COMMIT;
318-
EXCEPTION
319-
WHEN attempted_ddl_on_in_use_GTT THEN
320-
NULL; -- if it its a global temporary table, leave it alone.
321-
WHEN dne_942 THEN
322-
NULL;
323-
WHEN mv_dne_12003 THEN
324-
NULL;
325-
END;
303+
{{ oracle__get_drop_sql(relation) }}
326304
{%- endcall %}
327305
{% endmacro %}
328306

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{#
2+
Copyright (c) 2023, Oracle and/or its affiliates.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
https://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
#}
16+
{% macro oracle__collect_freshness(source, loaded_at_field, filter) %}
17+
{% call statement('collect_freshness', fetch_result=True, auto_begin=False) -%}
18+
select
19+
{% if loaded_at_field | upper == 'ORA_ROWSCN' %}
20+
SCN_TO_TIMESTAMP(max(ORA_ROWSCN)) as max_loaded_at,
21+
{% else %}
22+
max({{ loaded_at_field }}) as max_loaded_at,
23+
{% endif %}
24+
{{ current_timestamp() }} as snapshotted_at
25+
from {{ source }}
26+
{% if filter %}
27+
where {{ filter }}
28+
{% endif %}
29+
{% endcall %}
30+
{{ return(load_result('collect_freshness')) }}
31+
{% endmacro %}

dbt/include/oracle/macros/materializations/materialized_view/materialized_view.sql

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@
88
DROP MATERIALIZED VIEW {{ relation }}
99
{%- endmacro %}
1010

11-
{% macro oracle__get_replace_materialized_view_as_sql(relation, sql, existing_relation, backup_relation, intermediate_relation) %}
12-
{{ oracle__drop_relation(existing_relation) }}
13-
{{ oracle__get_create_materialized_view_as_sql(relation, sql) }}
14-
{% endmacro %}
1511

1612
{% macro oracle__get_create_materialized_view_as_sql(relation, sql) %}
1713
{%- set materialized_view = relation.from_runtime_config(config) -%}
@@ -30,13 +26,10 @@
3026
backup_relation,
3127
intermediate_relation
3228
) %}
33-
34-
-- apply a full refresh immediately if needed
3529
{% if configuration_changes.requires_full_refresh %}
36-
37-
{{ get_replace_materialized_view_as_sql(relation, sql, existing_relation, backup_relation, intermediate_relation) }}
38-
39-
-- otherwise apply individual changes as needed
30+
{{- log('Applying REPLACE to: ' ~ existing_relation ) -}}
31+
{{ oracle__drop_relation(existing_relation) }}
32+
{{ oracle__get_create_materialized_view_as_sql(relation, sql) }}
4033
{% else %}
4134

4235
{%- set refresh_method = configuration_changes.refresh_method -%}
@@ -80,3 +73,43 @@
8073
{% do return({'materialized_view': _materialized_view}) %}
8174
{%- endmacro %}
8275

76+
77+
{% macro materialized_view_get_build_sql(existing_relation, target_relation, backup_relation, intermediate_relation) %}
78+
79+
{% set full_refresh_mode = should_full_refresh() %}
80+
81+
-- determine the scenario we're in: create, full_refresh, alter, refresh data
82+
{% if existing_relation is none %}
83+
{% set build_sql = get_create_materialized_view_as_sql(target_relation, sql) %}
84+
{% elif full_refresh_mode or not existing_relation.is_materialized_view %}
85+
{{- log('Applying REPLACE to: ' ~ existing_relation ) -}}
86+
{{ oracle__drop_relation(existing_relation) }}
87+
{% set build_sql = oracle__get_create_materialized_view_as_sql(target_relation, sql) %}
88+
{% else %}
89+
90+
-- get config options
91+
{% set on_configuration_change = config.get('on_configuration_change') %}
92+
{% set configuration_changes = get_materialized_view_configuration_changes(existing_relation, config) %}
93+
94+
{% if configuration_changes is none %}
95+
{% set build_sql = refresh_materialized_view(target_relation) %}
96+
97+
{% elif on_configuration_change == 'apply' %}
98+
{% set build_sql = get_alter_materialized_view_as_sql(target_relation, configuration_changes, sql, existing_relation, backup_relation, intermediate_relation) %}
99+
{% elif on_configuration_change == 'continue' %}
100+
{% set build_sql = '' %}
101+
{{ exceptions.warn("Configuration changes were identified and `on_configuration_change` was set to `continue` for `" ~ target_relation ~ "`") }}
102+
{% elif on_configuration_change == 'fail' %}
103+
{{ exceptions.raise_fail_fast_error("Configuration changes were identified and `on_configuration_change` was set to `fail` for `" ~ target_relation ~ "`") }}
104+
105+
{% else %}
106+
-- this only happens if the user provides a value other than `apply`, 'skip', 'fail'
107+
{{ exceptions.raise_compiler_error("Unexpected configuration scenario") }}
108+
109+
{% endif %}
110+
111+
{% endif %}
112+
113+
{% do return(build_sql) %}
114+
115+
{% endmacro %}

0 commit comments

Comments
 (0)