-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat; add enum, refactor models file
- Loading branch information
Showing
11 changed files
with
186 additions
and
146 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
from .column import Column | ||
from .enums import MatchByColumnName, TagLevel | ||
from .file_format import FileFormat, InlineFileFormat | ||
from .schema import Schema | ||
from .table import Table | ||
from .table_structure import TableStructure | ||
|
||
__all__ = [ | ||
"Column", | ||
"MatchByColumnName", | ||
"TagLevel", | ||
"Schema", | ||
"Table", | ||
"TableStructure", | ||
"FileFormat", | ||
"InlineFileFormat", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
from datetime import date, datetime | ||
|
||
from pydantic import BaseModel, Field | ||
|
||
|
||
class Column(BaseModel): | ||
name: str | ||
data_type: str | ||
tags: dict[str, str] = Field(default_factory=dict) | ||
|
||
|
||
def _possibly_cast(s: str, old_column_type: str, new_column_type: str) -> str: | ||
if old_column_type == "VARIANT" and new_column_type != "VARIANT": | ||
return f"PARSE_JSON({s})" | ||
return s | ||
|
||
|
||
def _matched(columns: list[Column], old_columns: dict[str, str]): | ||
def tmp(x: str) -> str: | ||
return f'tmp."{x}"' | ||
|
||
return ",".join( | ||
f'dest."{c.name}" = {_possibly_cast(tmp(c.name), old_columns.get(c.name), c.data_type)}' | ||
for c in columns | ||
) | ||
|
||
|
||
def _inserts(columns: list[Column], old_columns: dict[str, str]) -> str: | ||
return ",".join( | ||
_possibly_cast(f'tmp."{c.name}"', old_columns.get(c.name), c.data_type) | ||
for c in columns | ||
) | ||
|
||
|
||
def _type_cast(s: any) -> any: | ||
if isinstance(s, (int, float)): | ||
return str(s) | ||
elif isinstance(s, str): | ||
return f"'{s}'" | ||
elif isinstance(s, (datetime, date)): | ||
return f"'{s.isoformat()}'" | ||
else: | ||
return f"'{s}'" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
from enum import Enum | ||
|
||
|
||
class MatchByColumnName(Enum): | ||
CASE_SENSITIVE = "CASE_SENSITIVE" | ||
CASE_INSENSITIVE = "CASE_INSENSITIVE" | ||
NONE = "NONE" | ||
|
||
|
||
class TagLevel(Enum): | ||
COLUMN = "column" | ||
TABLE = "table" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
from typing import Self | ||
|
||
from pydantic import BaseModel | ||
|
||
|
||
class InlineFileFormat(BaseModel): | ||
definition: str | ||
|
||
|
||
class FileFormat(BaseModel): | ||
database: str | None = None | ||
schema_: str | None = None | ||
name: str | ||
|
||
def __str__(self) -> str: | ||
return ".".join( | ||
s for s in [self.database, self.schema_, self.name] if s is not None | ||
) | ||
|
||
@classmethod | ||
def from_string(cls, s: str) -> Self: | ||
s = s.split(".") | ||
match s: | ||
case [database, schema, name]: | ||
return cls(database=database, schema_=schema, name=name) | ||
case [schema, name]: | ||
return cls(schema_=schema, name=name) | ||
case [name]: | ||
return cls(name=name) | ||
case _: | ||
raise ValueError("Cannot parse file format") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
from pydantic import BaseModel | ||
from snowflake.connector.cursor import SnowflakeCursor | ||
|
||
from .table import Table | ||
|
||
|
||
class Schema(BaseModel): | ||
name: str | ||
database: str | None = None | ||
|
||
@property | ||
def fully_qualified_name(self): | ||
if self.database: | ||
return f"{self.database}.{self.name}" | ||
else: | ||
return self.name | ||
|
||
def get_tables(self, cursor: SnowflakeCursor): | ||
cursor.execute(f"show tables in schema {self.fully_qualified_name};") | ||
data = cursor.execute( | ||
'select "name", "database_name", "schema_name" FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()));' | ||
).fetchall() | ||
return [ | ||
Table(name=name, schema_=schema, database=database) | ||
for (name, database, schema, *_) in data | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
from pydantic import BaseModel, Field, field_validator | ||
|
||
from .column import Column | ||
|
||
|
||
class TableStructure(BaseModel): | ||
columns: dict = [str, Column] | ||
tags: dict[str, str] = Field(default_factory=dict) | ||
|
||
@property | ||
def parsed_columns(self, replace_chars: bool = False) -> str: | ||
if replace_chars: | ||
return ", ".join( | ||
f'"{str.upper(k).strip().replace("-","_")}" {v.data_type}' | ||
for k, v in self.columns.items() | ||
) | ||
else: | ||
return ", ".join( | ||
f'"{str.upper(k).strip()}" {v.data_type}' | ||
for k, v in self.columns.items() | ||
) | ||
|
||
def parse_from_json(self): | ||
raise NotImplementedError("Not implemented yet") | ||
|
||
@field_validator("columns") | ||
@classmethod | ||
def force_columns_to_casefold(cls, value) -> dict: | ||
return {k.casefold(): v for k, v in value.items()} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.