Skip to content

Commit

Permalink
Merge branch 'main' into standardize_load_methods
Browse files Browse the repository at this point in the history
  • Loading branch information
edgarrmondragon authored Sep 12, 2023
2 parents 430cebb + 50c4725 commit 1307a37
Show file tree
Hide file tree
Showing 22 changed files with 167 additions and 81 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/dependency-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:

- name: GitHub dependency vulnerability check
if: ${{ github.event_name == 'pull_request_target' }}
uses: actions/dependency-review-action@v3.0.8
uses: actions/dependency-review-action@v3.1.0
with:
fail-on-severity: high

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/version_bump.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:

- name: Bump version
id: cz-bump
uses: commitizen-tools/commitizen-action@0.18.2
uses: commitizen-tools/commitizen-action@0.19.0
with:
increment: ${{ github.event.inputs.bump != 'auto' && github.event.inputs.bump || '' }}
prerelease: ${{ github.event.inputs.prerelease != 'none' && github.event.inputs.prerelease || '' }}
Expand Down
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ repos:
- id: check-readthedocs

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.0.287
rev: v0.0.288
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix, --show-fixes]
Expand All @@ -53,7 +53,7 @@ repos:
)$
- repo: https://github.com/psf/black
rev: 23.7.0
rev: 23.9.1
hooks:
- id: black
exclude: |
Expand Down
16 changes: 13 additions & 3 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Empty file.
32 changes: 32 additions & 0 deletions samples/sample_custom_sql_adapter/connector.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from __future__ import annotations

import typing as t

from sqlalchemy.engine.default import DefaultDialect

if t.TYPE_CHECKING:
from types import ModuleType


class CustomSQLDialect(DefaultDialect):
"""Custom SQLite dialect that supports JSON."""

name = "myrdbms"

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

@classmethod
def import_dbapi(cls):
"""Import the sqlite3 DBAPI."""
import sqlite3

return sqlite3

@classmethod
def dbapi(cls) -> ModuleType: # type: ignore[override]
"""Return the DBAPI module.
NOTE: This is a legacy method that will stop being used by SQLAlchemy at some point.
""" # noqa: E501
return cls.import_dbapi()
21 changes: 15 additions & 6 deletions singer_sdk/connectors/sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,12 +321,21 @@ def create_engine(self) -> Engine:
Returns:
A new SQLAlchemy Engine.
"""
return sqlalchemy.create_engine(
self.sqlalchemy_url,
echo=False,
json_serializer=self.serialize_json,
json_deserializer=self.deserialize_json,
)
try:
return sqlalchemy.create_engine(
self.sqlalchemy_url,
echo=False,
json_serializer=self.serialize_json,
json_deserializer=self.deserialize_json,
)
except TypeError:
self.logger.exception(
"Retrying engine creation with fewer arguments due to TypeError.",
)
return sqlalchemy.create_engine(
self.sqlalchemy_url,
echo=False,
)

def quote(self, name: str) -> str:
"""Quote a name if it needs quoting, using '.' as a name-part delimiter.
Expand Down
27 changes: 7 additions & 20 deletions singer_sdk/helpers/_flattening.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

import collections
import itertools
import json
import re
import typing as t
from copy import deepcopy

import inflection
import simplejson as json

DEFAULT_FLATTENING_SEPARATOR = "__"

Expand Down Expand Up @@ -155,17 +155,7 @@ def flatten_schema(
"type": "string"
},
"foo__bar": {
"type": "object",
"properties": {
"baz": {
"type": "object",
"properties": {
"qux": {
"type": "string"
}
}
}
}
"type": "string"
}
}
}
Expand All @@ -178,12 +168,7 @@ def flatten_schema(
"type": "string"
},
"foo__bar__baz": {
"type": "object",
"properties": {
"qux": {
"type": "string"
}
}
"type": "string"
}
}
}
Expand All @@ -210,7 +195,7 @@ def flatten_schema(
return new_schema


def _flatten_schema( # noqa: C901
def _flatten_schema( # noqa: C901, PLR0912
schema_node: dict,
parent_keys: list[str] | None = None,
separator: str = "__",
Expand Down Expand Up @@ -249,6 +234,8 @@ def _flatten_schema( # noqa: C901
max_level=max_level,
).items(),
)
elif "array" in v["type"] or "object" in v["type"] and max_level > 0:
items.append((new_key, {"type": "string"}))
else:
items.append((new_key, v))
elif len(v.values()) > 0:
Expand Down Expand Up @@ -347,7 +334,7 @@ def _flatten_record(
items.append(
(
new_key,
json.dumps(v)
json.dumps(v, use_decimal=True)
if _should_jsondump_value(k, v, flattened_schema)
else v,
),
Expand Down
21 changes: 20 additions & 1 deletion tests/core/test_connector_sql.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
from __future__ import annotations

import typing as t
from decimal import Decimal
from unittest import mock

import pytest
import sqlalchemy
from sqlalchemy.dialects import sqlite
from sqlalchemy.dialects import registry, sqlite

from singer_sdk.connectors import SQLConnector
from singer_sdk.exceptions import ConfigValidationError

if t.TYPE_CHECKING:
from sqlalchemy.engine import Engine


def stringify(in_dict):
return {k: str(v) for k, v in in_dict.items()}
Expand Down Expand Up @@ -283,3 +287,18 @@ def test_engine_json_serialization(self, connector: SQLConnector):
(1, {"x": Decimal("1.0")}),
(2, {"x": Decimal("2.0"), "y": [1, 2, 3]}),
]


def test_adapter_without_json_serde():
registry.register(
"myrdbms",
"samples.sample_custom_sql_adapter.connector",
"CustomSQLDialect",
)

class CustomConnector(SQLConnector):
def create_engine(self) -> Engine:
return super().create_engine()

connector = CustomConnector(config={"sqlalchemy_url": "myrdbms:///"})
connector.create_engine()
29 changes: 26 additions & 3 deletions tests/core/test_mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import logging
import typing as t
from contextlib import redirect_stdout
from decimal import Decimal

import pytest
from freezegun import freeze_time
Expand All @@ -19,7 +20,9 @@
from singer_sdk.streams.core import Stream
from singer_sdk.tap_base import Tap
from singer_sdk.typing import (
ArrayType,
IntegerType,
NumberType,
ObjectType,
PropertiesList,
Property,
Expand Down Expand Up @@ -415,6 +418,7 @@ class MappedStream(Stream):
ObjectType(
Property("id", IntegerType()),
Property("sub", ObjectType(Property("num", IntegerType()))),
Property("some_numbers", ArrayType(NumberType())),
),
),
).to_dict()
Expand All @@ -423,17 +427,29 @@ def get_records(self, context): # noqa: ARG002
yield {
"email": "[email protected]",
"count": 21,
"user": {"id": 1, "sub": {"num": 1}},
"user": {
"id": 1,
"sub": {"num": 1},
"some_numbers": [Decimal("3.14"), Decimal("2.718")],
},
}
yield {
"email": "[email protected]",
"count": 13,
"user": {"id": 2, "sub": {"num": 2}},
"user": {
"id": 2,
"sub": {"num": 2},
"some_numbers": [Decimal("10.32"), Decimal("1.618")],
},
}
yield {
"email": "[email protected]",
"count": 19,
"user": {"id": 3, "sub": {"num": 3}},
"user": {
"id": 3,
"sub": {"num": 3},
"some_numbers": [Decimal("1.414"), Decimal("1.732")],
},
}


Expand Down Expand Up @@ -545,6 +561,13 @@ def _clear_schema_cache() -> None:
"aliased_stream.jsonl",
id="aliased_stream",
),
pytest.param(
{},
True,
0,
"flatten_depth_0.jsonl",
id="flatten_depth_0",
),
pytest.param(
{},
True,
Expand Down
8 changes: 4 additions & 4 deletions tests/snapshots/mapped_stream/aliased_stream.jsonl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{"type": "STATE", "value": {}}
{"type": "SCHEMA", "stream": "aliased_stream", "schema": {"properties": {"email": {"type": ["string", "null"]}, "count": {"type": ["integer", "null"]}, "user": {"properties": {"id": {"type": ["integer", "null"]}, "sub": {"properties": {"num": {"type": ["integer", "null"]}}, "type": ["object", "null"]}}, "type": ["object", "null"]}}, "type": "object"}, "key_properties": []}
{"type": "RECORD", "stream": "aliased_stream", "record": {"email": "[email protected]", "count": 21, "user": {"id": 1, "sub": {"num": 1}}}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "RECORD", "stream": "aliased_stream", "record": {"email": "[email protected]", "count": 13, "user": {"id": 2, "sub": {"num": 2}}}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "RECORD", "stream": "aliased_stream", "record": {"email": "[email protected]", "count": 19, "user": {"id": 3, "sub": {"num": 3}}}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "SCHEMA", "stream": "aliased_stream", "schema": {"properties": {"email": {"type": ["string", "null"]}, "count": {"type": ["integer", "null"]}, "user": {"properties": {"id": {"type": ["integer", "null"]}, "sub": {"properties": {"num": {"type": ["integer", "null"]}}, "type": ["object", "null"]}, "some_numbers": {"items": {"type": ["number"]}, "type": ["array", "null"]}}, "type": ["object", "null"]}}, "type": "object"}, "key_properties": []}
{"type": "RECORD", "stream": "aliased_stream", "record": {"email": "[email protected]", "count": 21, "user": {"id": 1, "sub": {"num": 1}, "some_numbers": [3.14, 2.718]}}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "RECORD", "stream": "aliased_stream", "record": {"email": "[email protected]", "count": 13, "user": {"id": 2, "sub": {"num": 2}, "some_numbers": [10.32, 1.618]}}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "RECORD", "stream": "aliased_stream", "record": {"email": "[email protected]", "count": 19, "user": {"id": 3, "sub": {"num": 3}, "some_numbers": [1.414, 1.732]}}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "STATE", "value": {"bookmarks": {"mystream": {}}}}
8 changes: 4 additions & 4 deletions tests/snapshots/mapped_stream/drop_property.jsonl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{"type": "STATE", "value": {}}
{"type": "SCHEMA", "stream": "mystream", "schema": {"properties": {"count": {"type": ["integer", "null"]}, "user": {"properties": {"id": {"type": ["integer", "null"]}, "sub": {"properties": {"num": {"type": ["integer", "null"]}}, "type": ["object", "null"]}}, "type": ["object", "null"]}}, "type": "object"}, "key_properties": []}
{"type": "RECORD", "stream": "mystream", "record": {"count": 21, "user": {"id": 1, "sub": {"num": 1}}}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "RECORD", "stream": "mystream", "record": {"count": 13, "user": {"id": 2, "sub": {"num": 2}}}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "RECORD", "stream": "mystream", "record": {"count": 19, "user": {"id": 3, "sub": {"num": 3}}}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "SCHEMA", "stream": "mystream", "schema": {"properties": {"count": {"type": ["integer", "null"]}, "user": {"properties": {"id": {"type": ["integer", "null"]}, "sub": {"properties": {"num": {"type": ["integer", "null"]}}, "type": ["object", "null"]}, "some_numbers": {"items": {"type": ["number"]}, "type": ["array", "null"]}}, "type": ["object", "null"]}}, "type": "object"}, "key_properties": []}
{"type": "RECORD", "stream": "mystream", "record": {"count": 21, "user": {"id": 1, "sub": {"num": 1}, "some_numbers": [3.14, 2.718]}}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "RECORD", "stream": "mystream", "record": {"count": 13, "user": {"id": 2, "sub": {"num": 2}, "some_numbers": [10.32, 1.618]}}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "RECORD", "stream": "mystream", "record": {"count": 19, "user": {"id": 3, "sub": {"num": 3}, "some_numbers": [1.414, 1.732]}}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "STATE", "value": {"bookmarks": {"mystream": {}}}}
8 changes: 4 additions & 4 deletions tests/snapshots/mapped_stream/drop_property_null_string.jsonl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{"type": "STATE", "value": {}}
{"type": "SCHEMA", "stream": "mystream", "schema": {"properties": {"count": {"type": ["integer", "null"]}, "user": {"properties": {"id": {"type": ["integer", "null"]}, "sub": {"properties": {"num": {"type": ["integer", "null"]}}, "type": ["object", "null"]}}, "type": ["object", "null"]}}, "type": "object"}, "key_properties": []}
{"type": "RECORD", "stream": "mystream", "record": {"count": 21, "user": {"id": 1, "sub": {"num": 1}}}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "RECORD", "stream": "mystream", "record": {"count": 13, "user": {"id": 2, "sub": {"num": 2}}}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "RECORD", "stream": "mystream", "record": {"count": 19, "user": {"id": 3, "sub": {"num": 3}}}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "SCHEMA", "stream": "mystream", "schema": {"properties": {"count": {"type": ["integer", "null"]}, "user": {"properties": {"id": {"type": ["integer", "null"]}, "sub": {"properties": {"num": {"type": ["integer", "null"]}}, "type": ["object", "null"]}, "some_numbers": {"items": {"type": ["number"]}, "type": ["array", "null"]}}, "type": ["object", "null"]}}, "type": "object"}, "key_properties": []}
{"type": "RECORD", "stream": "mystream", "record": {"count": 21, "user": {"id": 1, "sub": {"num": 1}, "some_numbers": [3.14, 2.718]}}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "RECORD", "stream": "mystream", "record": {"count": 13, "user": {"id": 2, "sub": {"num": 2}, "some_numbers": [10.32, 1.618]}}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "RECORD", "stream": "mystream", "record": {"count": 19, "user": {"id": 3, "sub": {"num": 3}, "some_numbers": [1.414, 1.732]}}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "STATE", "value": {"bookmarks": {"mystream": {}}}}
8 changes: 4 additions & 4 deletions tests/snapshots/mapped_stream/flatten_all.jsonl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{"type": "STATE", "value": {}}
{"type": "SCHEMA", "stream": "mystream", "schema": {"properties": {"email": {"type": ["string", "null"]}, "count": {"type": ["integer", "null"]}, "user__id": {"type": ["integer", "null"]}, "user__sub__num": {"type": ["integer", "null"]}}, "type": "object"}, "key_properties": []}
{"type": "RECORD", "stream": "mystream", "record": {"email": "[email protected]", "count": 21, "user__id": 1, "user__sub__num": 1}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "RECORD", "stream": "mystream", "record": {"email": "[email protected]", "count": 13, "user__id": 2, "user__sub__num": 2}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "RECORD", "stream": "mystream", "record": {"email": "[email protected]", "count": 19, "user__id": 3, "user__sub__num": 3}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "SCHEMA", "stream": "mystream", "schema": {"properties": {"email": {"type": ["string", "null"]}, "count": {"type": ["integer", "null"]}, "user__id": {"type": ["integer", "null"]}, "user__sub__num": {"type": ["integer", "null"]}, "user__some_numbers": {"type": "string"}}, "type": "object"}, "key_properties": []}
{"type": "RECORD", "stream": "mystream", "record": {"email": "[email protected]", "count": 21, "user__id": 1, "user__sub__num": 1, "user__some_numbers": "[3.14, 2.718]"}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "RECORD", "stream": "mystream", "record": {"email": "[email protected]", "count": 13, "user__id": 2, "user__sub__num": 2, "user__some_numbers": "[10.32, 1.618]"}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "RECORD", "stream": "mystream", "record": {"email": "[email protected]", "count": 19, "user__id": 3, "user__sub__num": 3, "user__some_numbers": "[1.414, 1.732]"}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "STATE", "value": {"bookmarks": {"mystream": {}}}}
6 changes: 6 additions & 0 deletions tests/snapshots/mapped_stream/flatten_depth_0.jsonl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{"type": "STATE", "value": {}}
{"type": "SCHEMA", "stream": "mystream", "schema": {"properties": {"email": {"type": ["string", "null"]}, "count": {"type": ["integer", "null"]}, "user": {"properties": {"id": {"type": ["integer", "null"]}, "sub": {"properties": {"num": {"type": ["integer", "null"]}}, "type": ["object", "null"]}, "some_numbers": {"items": {"type": ["number"]}, "type": ["array", "null"]}}, "type": ["object", "null"]}}, "type": "object"}, "key_properties": []}
{"type": "RECORD", "stream": "mystream", "record": {"email": "[email protected]", "count": 21, "user": {"id": 1, "sub": {"num": 1}, "some_numbers": [3.14, 2.718]}}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "RECORD", "stream": "mystream", "record": {"email": "[email protected]", "count": 13, "user": {"id": 2, "sub": {"num": 2}, "some_numbers": [10.32, 1.618]}}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "RECORD", "stream": "mystream", "record": {"email": "[email protected]", "count": 19, "user": {"id": 3, "sub": {"num": 3}, "some_numbers": [1.414, 1.732]}}, "time_extracted": "2022-01-01T00:00:00+00:00"}
{"type": "STATE", "value": {"bookmarks": {"mystream": {}}}}
Loading

0 comments on commit 1307a37

Please sign in to comment.