Skip to content

Commit c1df271

Browse files
authored
Merge pull request #27 from oracle/feature/dbt-core_v1.1
Feature/dbt core v1.1
2 parents ba7ace1 + 18f0de7 commit c1df271

27 files changed

+639
-412
lines changed

.github/scripts/create_new_user.sh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/bin/bash
2+
3+
set -Exeuo pipefail
4+
5+
# Parameters
6+
DB_USER="${1}"
7+
DB_PASSWORD="${2}"
8+
TARGET_PDB="${3:-XEPDB1}"
9+
10+
# Prepare container switch statement to create user in PDB.
11+
ALTER_SESSION_CMD="ALTER SESSION SET CONTAINER=${TARGET_PDB};"
12+
13+
# 11g XE does not support PDBs, set container switch statement to empty string.
14+
ORACLE_VERSION=$(sqlplus -version | grep "Release" | awk '{ print $3 }')
15+
if [[ "${ORACLE_VERSION}" = "11.2"* ]]; then
16+
ALTER_SESSION_CMD="";
17+
fi;
18+
19+
# Create new user in target PDB
20+
sqlplus -s / as sysdba << EOF
21+
-- Exit on any errors
22+
WHENEVER SQLERROR EXIT SQL.SQLCODE
23+
${ALTER_SESSION_CMD}
24+
CREATE USER ${DB_USER} IDENTIFIED BY "${DB_PASSWORD}" QUOTA UNLIMITED ON USERS;
25+
GRANT ALL PRIVILEGES TO ${DB_USER};
26+
exit;
27+
EOF
Lines changed: 13 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
1-
name: dbt-adapter-tests
1+
name: dbt-tests-adapter
22
on: push
33

44
jobs:
5-
oracle-21_3_0-xe-test-suite:
5+
oracle_xe_21_3:
66
runs-on: ${{ matrix.os }}
77
strategy:
88
fail-fast: true
99
matrix:
1010
os: [ ubuntu-latest ]
11-
python-version: [ 3.7, 3.8, 3.9 ]
11+
python-version: [ '3.7', '3.8', '3.9', '3.10' ]
1212

1313
services:
1414
oracle_db_xe:
1515
image: container-registry.oracle.com/database/express:21.3.0-xe
1616
env:
1717
ORACLE_PWD: ${{ secrets.DBT_ORACLE_PASSWORD }}
18+
options: --name oracle_db_xe
1819
ports:
1920
- 1521:1521
2021

@@ -32,81 +33,34 @@ jobs:
3233
chmod +x ${{ github.workspace }}/.github/scripts/install_oracle_instantclient.sh
3334
${{ github.workspace }}/.github/scripts/install_oracle_instantclient.sh
3435
35-
- name: Install dbt-oracle with core dependencies
36-
run: |
37-
python -m pip install --upgrade pip
38-
pip install pytest pytest-dbt-adapter==0.6.0
39-
pip install -r requirements.txt
40-
pip install -e .
41-
42-
- name: Run adapter tests
36+
- name: Copy Create User script
4337
run: |
44-
pytest tests/oracle.dbtspec tests/test_config.py
45-
env:
46-
DBT_ORACLE_USER: ${{ secrets.DBT_ORACLE_USER }}
47-
DBT_ORACLE_HOST: localhost
48-
DBT_ORACLE_PORT: 1521
49-
DBT_ORACLE_SCHEMA: ${{ secrets.DBT_ORACLE_USER }}
50-
DBT_ORACLE_PASSWORD: ${{ secrets.DBT_ORACLE_PASSWORD }}
51-
DBT_ORACLE_DATABASE: XEPDB1
52-
DBT_ORACLE_SERVICE: XEPDB1
53-
DBT_ORACLE_PROTOCOL: tcp
54-
LD_LIBRARY_PATH: /opt/oracle/instantclient_21_6
55-
TNS_ADMIN: /opt/tns_admin
56-
57-
oracle-21_3_0-xe-py36-test-suite:
58-
runs-on: ${{ matrix.os }}
59-
strategy:
60-
fail-fast: true
61-
matrix:
62-
os: [ ubuntu-latest ]
63-
python-version: [ 3.6 ]
64-
65-
services:
66-
oracle_db_xe:
67-
image: container-registry.oracle.com/database/express:21.3.0-xe
68-
env:
69-
ORACLE_PWD: ${{ secrets.DBT_ORACLE_PASSWORD }}
70-
ports:
71-
- 1521:1521
72-
73-
steps:
74-
- name: Check out dbt-oracle repository code
75-
uses: actions/checkout@v3
38+
chmod +x ${{ github.workspace }}/.github/scripts/create_new_user.sh
39+
docker cp ${{ github.workspace }}/.github/scripts/create_new_user.sh oracle_db_xe:/home/oracle/create_new_user.sh
7640
77-
- name: Set up Python ${{ matrix.python-version }}
78-
uses: actions/setup-python@v3
79-
with:
80-
python-version: ${{ matrix.python-version }}
81-
82-
- name: Install Oracle Instantclient
41+
- name: Create dbt test user
8342
run: |
84-
chmod +x ${{ github.workspace }}/.github/scripts/install_oracle_instantclient.sh
85-
${{ github.workspace }}/.github/scripts/install_oracle_instantclient.sh
43+
docker exec oracle_db_xe /home/oracle/create_new_user.sh dbt_test ${{ secrets.DBT_ORACLE_PASSWORD }}
8644
8745
- name: Install dbt-oracle with core dependencies
8846
run: |
8947
python -m pip install --upgrade pip
90-
pip install pytest pytest-dbt-adapter==0.4.0
48+
pip install pytest dbt-tests-adapter==1.1.1
9149
pip install -r requirements.txt
9250
pip install -e .
9351
9452
- name: Run adapter tests
9553
run: |
96-
pytest tests/oracle_py36.dbtspec tests/test_config.py
54+
pytest
9755
env:
98-
DBT_ORACLE_USER: ${{ secrets.DBT_ORACLE_USER }}
56+
DBT_ORACLE_USER: DBT_TEST
9957
DBT_ORACLE_HOST: localhost
10058
DBT_ORACLE_PORT: 1521
101-
DBT_ORACLE_SCHEMA: ${{ secrets.DBT_ORACLE_USER }}
59+
DBT_ORACLE_SCHEMA: DBT_TEST
10260
DBT_ORACLE_PASSWORD: ${{ secrets.DBT_ORACLE_PASSWORD }}
10361
DBT_ORACLE_DATABASE: XEPDB1
10462
DBT_ORACLE_SERVICE: XEPDB1
10563
DBT_ORACLE_PROTOCOL: tcp
10664
LD_LIBRARY_PATH: /opt/oracle/instantclient_21_6
10765
TNS_ADMIN: /opt/tns_admin
10866

109-
110-
111-
112-

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,5 @@ doc/build.gitbak
141141
.venvpy37
142142
.venv1.1.0
143143
.venv
144-
.bldenv
144+
.bldenv
145+

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Configuration variables
2-
VERSION=1.0.4
2+
VERSION=1.1.0
33
PROJ_DIR?=$(shell pwd)
44
VENV_DIR?=${PROJ_DIR}/.bldenv
55
BUILD_DIR=${PROJ_DIR}/build
@@ -26,6 +26,7 @@ adbs_local_env_test: wheel clean_venv
2626
${VENV_DIR}/bin/pip install ${DIST_DIR}/dbt_oracle-${VERSION}-py3-none-any.whl
2727
cd dbt_adbs_test_project && ${VENV_DIR}/bin/dbt --version
2828
cd dbt_adbs_test_project && ${VENV_DIR}/bin/dbt debug --profiles-dir ./
29+
cd dbt_adbs_test_project && ${VENV_DIR}/bin/dbt deps --profiles-dir ./
2930
cd dbt_adbs_test_project && ${VENV_DIR}/bin/dbt run-operation drop_schema --args 'relation: ${DBT_ORACLE_SCHEMA}' --profiles-dir ./
3031
cd dbt_adbs_test_project && ${VENV_DIR}/bin/dbt deps --profiles-dir ./
3132
cd dbt_adbs_test_project && ${VENV_DIR}/bin/dbt seed --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.0.8"
17+
version = "1.1.1"

dbt/adapters/oracle/connections.py

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
See the License for the specific language governing permissions and
1515
limitations under the License.
1616
"""
17-
from typing import List, Optional, Tuple, Any, Dict
17+
from typing import List, Optional, Tuple, Any, Dict, Union
1818
from contextlib import contextmanager
1919
from dataclasses import dataclass, field
2020
import enum
@@ -24,20 +24,13 @@
2424
from cx_Oracle import Connection
2525

2626
import dbt.exceptions
27-
from dbt.helper_types import Port
2827

2928
from dbt.adapters.base import Credentials
3029
from dbt.adapters.sql import SQLConnectionManager
3130
from dbt.contracts.connection import AdapterResponse
31+
from dbt.events import AdapterLogger
3232

33-
# dbt.events was introduced in dbt-core==1.0.0 which only supports Python 3.7
34-
# For Python 3.6, we fallback to the old logger in dbt.logger.
35-
try:
36-
from dbt.events import AdapterLogger
37-
logger = AdapterLogger("oracle")
38-
except ImportError:
39-
from dbt.logger import GLOBAL_LOGGER as logger
40-
33+
logger = AdapterLogger("oracle")
4134

4235

4336
class OracleConnectionMethod(enum.Enum):
@@ -65,7 +58,7 @@ class OracleAdapterCredentials(Credentials):
6558
# OracleConnectionMethod.HOST
6659
protocol: Optional[str] = None
6760
host: Optional[str] = None
68-
port: Optional[Port] = None
61+
port: Optional[Union[str, int]] = None
6962
service: Optional[str] = None
7063

7164
# OracleConnectionMethod.CONNECTION_STRING

dbt/include/oracle/macros/adapters.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,13 +234,13 @@
234234
{%- set tmp_column = column_name + "__dbt_alter" -%}
235235

236236
{% call statement('alter_column_type 1', fetch_result=False) %}
237-
alter table {{ relation.include(False, True, True).quote(schema=False, identifier=False) }} add column {{ tmp_column }} {{ new_column_type }}
237+
alter table {{ relation.include(False, True, True).quote(schema=False, identifier=False) }} add {{ tmp_column }} {{ new_column_type }}
238238
{% endcall %}
239239
{% call statement('alter_column_type 2', fetch_result=False) %}
240240
update {{ relation.include(False, True, True).quote(schema=False, identifier=False) }} set {{ tmp_column }} = {{ column_name }}
241241
{% endcall %}
242242
{% call statement('alter_column_type 3', fetch_result=False) %}
243-
alter table {{ relation.include(False, True, True).quote(schema=False, identifier=False) }} drop column {{ column_name }} cascade
243+
alter table {{ relation.include(False, True, True).quote(schema=False, identifier=False) }} drop column {{ column_name }} cascade constraints
244244
{% endcall %}
245245
{% call statement('alter_column_type 4', fetch_result=False) %}
246246
alter table {{ relation.include(False, True, True).quote(schema=False, identifier=False) }} rename column {{ tmp_column }} to {{ column_name }}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{#
2+
Copyright (c) 2022, Oracle and/or its affiliates.
3+
Copyright (c) 2020, Vitor Avancini
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
https://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
#}
17+
{% macro oracle__alter_relation_add_remove_columns(relation, add_columns, remove_columns) %}
18+
19+
{% if add_columns is none %}
20+
{% set add_columns = [] %}
21+
{% endif %}
22+
{% if remove_columns is none %}
23+
{% set remove_columns = [] %}
24+
{% endif %}
25+
26+
{% set sql -%}
27+
28+
alter {{ relation.type }} {{ relation }}
29+
30+
{% for column in add_columns %}
31+
add {{ column.name }} {{ column.data_type }}{{ ',' if not loop.last }}
32+
{% endfor %}{{ ',' if add_columns and remove_columns }}
33+
34+
{% for column in remove_columns %}
35+
drop column {{ column.name }}{{ ',' if not loop.last }}
36+
{% endfor %}
37+
38+
{%- endset -%}
39+
40+
{% do run_query(sql) %}
41+
{% endmacro %}

dbt/include/oracle/macros/materializations/incremental/helpers.sql

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,26 +34,40 @@
3434
)
3535
{%- endmacro %}
3636

37-
{% macro oracle_incremental_upsert(tmp_relation, target_relation, unique_key=none, statement_name="main") %}
38-
{%- set dest_columns = adapter.get_columns_in_relation(target_relation) -%}
37+
{% macro oracle_incremental_upsert(tmp_relation, target_relation, dest_columns, unique_key=none, statement_name="main") %}
38+
{%- set on_predicates = [] -%}
39+
{%- set unique_key_list = [] -%}
3940
{%- set dest_cols_csv = dest_columns | map(attribute='name') | join(', ') -%}
4041

41-
{%- if unique_key is not none -%}
42-
merge into {{ target_relation }} target
43-
using {{ tmp_relation }} temp
44-
on (temp.{{ unique_key }} = target.{{ unique_key }})
45-
when matched then
46-
update set
47-
{% for col in dest_columns if col.name.upper() != unique_key.upper() -%}
48-
target.{{ col.name }} = temp.{{ col.name }}{% if not loop.last %}, {% endif %}
49-
{% endfor -%}
50-
when not matched then
51-
insert({{ dest_cols_csv }})
52-
values(
53-
{% for col in dest_columns -%}
54-
temp.{{ col.name }}{% if not loop.last %}, {% endif %}
55-
{% endfor -%}
56-
)
42+
{%- if unique_key -%}
43+
{% if unique_key is sequence and unique_key is not mapping and unique_key is not string %}
44+
{% for key in unique_key | unique %}
45+
{% do unique_key_list.append(key.upper()) %}
46+
{% endfor %}
47+
{% else %}
48+
{% do unique_key_list.append(unique_key.upper()) %}
49+
{% endif %}
50+
{% for key in unique_key_list %}
51+
{% set this_key_match %}
52+
temp.{{ key }} = target.{{ key }}
53+
{% endset %}
54+
{% do on_predicates.append(this_key_match) %}
55+
{% endfor %}
56+
merge into {{ target_relation }} target
57+
using {{ tmp_relation }} temp
58+
on ({{ on_predicates | join(' AND ') }})
59+
when matched then
60+
update set
61+
{% for col in dest_columns if col.name.upper() not in unique_key_list -%}
62+
target.{{ col.name }} = temp.{{ col.name }}{% if not loop.last %}, {% endif %}
63+
{% endfor -%}
64+
when not matched then
65+
insert({{ dest_cols_csv }})
66+
values(
67+
{% for col in dest_columns -%}
68+
temp.{{ col.name }}{% if not loop.last %}, {% endif %}
69+
{% endfor -%}
70+
)
5771
{%- else -%}
5872
insert into {{ target_relation }} ({{ dest_cols_csv }})
5973
(

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
{% set target_relation = this.incorporate(type='table') %}
2323
{% set existing_relation = load_relation(this) %}
2424
{% set tmp_relation = make_temp_relation(this) %}
25+
{% set on_schema_change = incremental_validate_on_schema_change(config.get('on_schema_change'), default='ignore') %}
26+
2527

2628
{{ run_hooks(pre_hooks, inside_transaction=False) }}
2729

@@ -50,7 +52,11 @@
5052
{% do adapter.expand_target_column_types(
5153
from_relation=tmp_relation,
5254
to_relation=target_relation) %}
53-
{% set build_sql = oracle_incremental_upsert(tmp_relation, target_relation, unique_key=unique_key) %}
55+
{% set dest_columns = process_schema_changes(on_schema_change, tmp_relation, existing_relation) %}
56+
{% if not dest_columns %}
57+
{% set dest_columns = adapter.get_columns_in_relation(existing_relation) %}
58+
{% endif %}
59+
{% set build_sql = oracle_incremental_upsert(tmp_relation, target_relation, dest_columns, unique_key=unique_key) %}
5460
{% endif %}
5561

5662
{% call statement("main") %}

0 commit comments

Comments
 (0)