Skip to content

Commit

Permalink
add NLS_DATE_FORMAT for Oracle (#372)
Browse files Browse the repository at this point in the history
* add NLS_DATE_FORMAT for Oracle

* add docstring

* docstring + remove None return type

---------

Co-authored-by: spicy-sauce <[email protected]>
  • Loading branch information
zalmane and spicy-sauce authored Aug 13, 2024
1 parent 2dbd485 commit 3d3cb18
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 3 deletions.
22 changes: 22 additions & 0 deletions core/src/datayoga_core/blocks/relational/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import sqlalchemy as sa
from datayoga_core.connection import Connection
from datayoga_core.context import Context
from sqlalchemy.engine.interfaces import DBAPIConnection
from sqlalchemy.pool import ConnectionPoolEntry

logger = logging.getLogger("dy")

Expand Down Expand Up @@ -71,9 +73,29 @@ def get_engine(connection_name: str, context: Context, autocommit: bool = True)
pool_pre_ping=True,
**extra)

if db_type == DbType.ORACLE:
# add NLS_DATE_FORMAT for Oracle to explicitly set the date format to ISO
sa.event.listen(engine, "connect", alter_session_on_oracle_connect)

return engine, db_type


def alter_session_on_oracle_connect(dbapi_connection: DBAPIConnection, connection_record: ConnectionPoolEntry):
"""SQLAlchemy event listener to alter the Oracle session settings upon connection.
This callback function is intended to be used with SQLAlchemy's `connect` event.
It alters the Oracle session settings by setting the `NLS_DATE_FORMAT` for the session
to ensure that dates are formatted as 'YYYY-MM-DD HH24:MI:SS'.
Args:
dbapi_connection (DBAPIConnection): The raw DB-API connection object provided by the Oracle driver.
connection_record (ConnectionPoolEntry): A record associated with the connection, managed by SQLAlchemy.
"""
cursor = dbapi_connection.cursor()
cursor.execute("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'")
cursor.close()


def construct_table_reference(table: sa.Table, with_brackets: bool = False) -> str:
"""Constructs a table reference string.
Expand Down
7 changes: 4 additions & 3 deletions integration-tests/common/db_utils.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from typing import Any, Dict, Optional

from datayoga_core.blocks.relational.utils import DEFAULT_DRIVERS, DbType
from sqlalchemy import (Column, Integer, String, Table, create_engine, inspect,
text)
from sqlalchemy import (Column, DateTime, Integer, String, Table,
create_engine, inspect, text)
from sqlalchemy.engine import Engine
from sqlalchemy.orm import declarative_base
from testcontainers.core.generic import (ADDITIONAL_TRANSIENT_ERRORS,
Expand Down Expand Up @@ -107,7 +107,8 @@ def create_emp_table(engine: Engine, schema_name: Optional[str]):
Column("full_name", String(50)),
Column("country", String(50)),
Column("address", String(50)),
Column("gender", String(1))
Column("gender", String(1)),
Column("date_of_birth", DateTime())
]
Table("emp", base.metadata, *columns, schema=schema_name)

Expand Down
2 changes: 2 additions & 0 deletions integration-tests/common/redis_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def add_to_emp_stream(redis_client: Redis):
"_id": 1,
"fname": "john",
"lname": "doe",
"date_of_birth": "2012-12-13",
"country_code": 972,
"country_name": "israel",
"credit_card": "1234-1234-1234-1234",
Expand All @@ -75,6 +76,7 @@ def add_to_emp_stream(redis_client: Redis):
"_id": 2,
"fname": "jane",
"lname": "doe",
"date_of_birth": "2011-11-13",
"country_code": 972,
"country_name": "israel",
"credit_card": "1000-2000-3000-4000",
Expand Down
2 changes: 2 additions & 0 deletions integration-tests/resources/jobs/tests/redis_to_db2.dy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ steps:
country: concat([country_code, ' - ', upper(country_name)])
gender: gender
addresses: addresses
date_of_birth: date_of_birth
language: jmespath
- uses: relational.write
with:
Expand All @@ -30,6 +31,7 @@ steps:
- FULL_NAME: full_name
- country
- gender
- date_of_birth
- uses: relational.write
with:
connection: db2-hr
Expand Down
2 changes: 2 additions & 0 deletions integration-tests/resources/jobs/tests/redis_to_mysql.dy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ steps:
country: concat([country_code, ' - ', upper(country_name)])
gender: gender
addresses: addresses
date_of_birth: date_of_birth
language: jmespath
- uses: relational.write
with:
Expand All @@ -31,6 +32,7 @@ steps:
- full_name: fullname
- country
- gender
- date_of_birth
- uses: relational.write
with:
connection: mysql-hr
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ steps:
country: concat([country_code, ' - ', upper(country_name)])
gender: gender
addresses: addresses
date_of_birth: date_of_birth
language: jmespath
- uses: relational.write
with:
Expand All @@ -31,6 +32,7 @@ steps:
- full_name
- country
- gender
- date_of_birth
- uses: relational.write
with:
connection: oracle-hr
Expand Down
2 changes: 2 additions & 0 deletions integration-tests/resources/jobs/tests/redis_to_pg.dy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ steps:
country: concat([country_code, ' - ', upper(country_name)])
gender: gender
addresses: addresses
date_of_birth: date_of_birth
language: jmespath
- uses: relational.write
with:
Expand All @@ -31,6 +32,7 @@ steps:
- full_name
- country
- gender
- date_of_birth
- uses: relational.write
with:
connection: psql-hr
Expand Down
3 changes: 3 additions & 0 deletions integration-tests/test_redis_to_relational.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import datetime
import logging
from contextlib import suppress
from typing import Optional
Expand Down Expand Up @@ -77,7 +78,9 @@ def check_results(engine: Engine, schema_name: Optional[str]):
assert second_employee is not None
assert second_employee["full_name"] == "Jane Doe"
assert second_employee["country"] == "972 - ISRAEL"
assert second_employee["date_of_birth"] == datetime.datetime(2011, 11, 13, 0, 0)
assert second_employee["gender"] == "F"

# address was not in the inserted record. verify that additional columns are set to null
assert second_employee["address"] is None

Expand Down

0 comments on commit 3d3cb18

Please sign in to comment.