maisaedu-poormans-dms 1.1.88__tar.gz → 1.1.90__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/PKG-INFO +1 -1
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Connector.py +4 -2
- maisaedu-poormans-dms-1.1.90/maisaedu_poormans_dms/redshift_migration/Reader/SQLServerReader.py +88 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Reader/__init__.py +2 -1
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Services/AdapterSourceTarget.py +13 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Writer/GenericWriter.py +2 -2
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Writer/WriterCDC.py +2 -3
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms.egg-info/PKG-INFO +1 -1
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms.egg-info/SOURCES.txt +1 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/setup.py +1 -1
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/LICENSE +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/__init__.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/postgres_migration/Contracts/MigratorInterface.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/postgres_migration/Contracts/MigratorRowInterface.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/postgres_migration/Contracts/MigratorRowReaderInterface.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/postgres_migration/Contracts/MigratorRowWriterInterface.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/postgres_migration/Contracts/MigratorTableInterface.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/postgres_migration/Contracts/__init__.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/postgres_migration/Migrator.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/postgres_migration/MigratorRow/MigratorRow.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/postgres_migration/MigratorRow/Reader.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/postgres_migration/MigratorRow/Writer.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/postgres_migration/MigratorRow/__init__.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/postgres_migration/MigratorTable.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/postgres_migration/__init__.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_dynamo_migration/Connector.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_dynamo_migration/DynamoReplicator.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_dynamo_migration/Writer/WriterCDC.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_dynamo_migration/Writer/WriterFull.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_dynamo_migration/Writer/__init__.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_dynamo_migration/__init__.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_dynamo_migration/models/Struct.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_dynamo_migration/models/__init__.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_dynamo_migration/services/Struct.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_dynamo_migration/services/__init__.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Contracts/ReaderInterface.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Contracts/WriterInterface.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Contracts/__init__.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Logger.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/MigratorRedshift.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Models/ExtractionOperation.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Models/Struct.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Models/__init__.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Reader/GenericReader.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Reader/PostgresReader.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Services/ExtractionOperation.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Services/RelationExtraction.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Services/Struct.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Services/__init__.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Types.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Writer/WriterNonCDC.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Writer/__init__.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/__init__.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/sql_server_migration.py +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms.egg-info/dependency_links.txt +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms.egg-info/requires.txt +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms.egg-info/top_level.txt +0 -0
- {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/setup.cfg +0 -0
|
@@ -65,8 +65,10 @@ class Connector:
|
|
|
65
65
|
)
|
|
66
66
|
self.source_conn = engine.connect().execution_options(stream_results=True)
|
|
67
67
|
elif self.source_conn_type == SQLSERVER:
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
engine = create_engine(
|
|
69
|
+
f"mssql+pyodbc://{self.source_credentials['user']}:{self.source_credentials['password']}@{self.source_credentials['host']}:{self.source_credentials['port']}/{self.source_credentials['database']}?driver=ODBC+Driver+17+for+SQL+Server"
|
|
70
|
+
)
|
|
71
|
+
self.source_conn = engine.connect().execution_options(stream_results=True)
|
|
70
72
|
|
|
71
73
|
def close_source(self):
|
|
72
74
|
self.source_conn.close()
|
maisaedu-poormans-dms-1.1.90/maisaedu_poormans_dms/redshift_migration/Reader/SQLServerReader.py
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from ..Types import (
|
|
3
|
+
target_type_is_numeric,
|
|
4
|
+
LOCAL,
|
|
5
|
+
FULL,
|
|
6
|
+
INCREMENTAL,
|
|
7
|
+
)
|
|
8
|
+
from .GenericReader import GenericReader
|
|
9
|
+
from ..Contracts.ReaderInterface import ReaderInterface
|
|
10
|
+
|
|
11
|
+
class SQLServerReader(GenericReader, ReaderInterface):
|
|
12
|
+
def get_incremental_statement(self):
|
|
13
|
+
if (
|
|
14
|
+
(
|
|
15
|
+
self.struct.source_incremental_column is not None
|
|
16
|
+
and self.struct.target_incremental_column is not None
|
|
17
|
+
and (self.load_option is None)
|
|
18
|
+
) or (self.load_option == INCREMENTAL)
|
|
19
|
+
):
|
|
20
|
+
sql = f"""
|
|
21
|
+
select max("{self.struct.target_incremental_column}") as max_value
|
|
22
|
+
from "{self.struct.target_schema}"."{self.struct.target_table}"
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
cursor = self.migrator_redshift_connector.target_conn.cursor()
|
|
26
|
+
|
|
27
|
+
cursor.execute(sql)
|
|
28
|
+
result = cursor.fetchall()
|
|
29
|
+
|
|
30
|
+
if len(result) == 0 or result[0][0] is None:
|
|
31
|
+
sql_return = ""
|
|
32
|
+
self.load_option = FULL
|
|
33
|
+
else:
|
|
34
|
+
for c in self.struct.columns:
|
|
35
|
+
if c["target_name"] == self.struct.target_incremental_column:
|
|
36
|
+
target_type = c["target_type"]
|
|
37
|
+
|
|
38
|
+
if target_type_is_numeric(target_type):
|
|
39
|
+
sql_return = f'and "{self.struct.source_incremental_column}" > {result[0][0]}'
|
|
40
|
+
else:
|
|
41
|
+
if (
|
|
42
|
+
self.struct.incremental_interval_delta is None
|
|
43
|
+
or self.struct.incremental_interval_delta == ""
|
|
44
|
+
):
|
|
45
|
+
sql_return = f"and \"{self.struct.source_incremental_column}\" > '{result[0][0]}'"
|
|
46
|
+
else:
|
|
47
|
+
split = self.struct.incremental_interval_delta.split(" ")
|
|
48
|
+
date_string = result[0][0].strftime("%Y-%m-%d %H:%M:%S.%f")
|
|
49
|
+
date_string = date_string[:-3]
|
|
50
|
+
sql_return = f"and \"{self.struct.source_incremental_column}\" >= DATEADD({split[1]}, -{split[0]}, '{date_string}')"
|
|
51
|
+
|
|
52
|
+
self.load_option = INCREMENTAL
|
|
53
|
+
|
|
54
|
+
cursor.close()
|
|
55
|
+
|
|
56
|
+
return sql_return
|
|
57
|
+
else:
|
|
58
|
+
if (self.load_option is None):
|
|
59
|
+
self.load_option = FULL
|
|
60
|
+
return ""
|
|
61
|
+
|
|
62
|
+
def get_columns_source(self):
|
|
63
|
+
return " * "
|
|
64
|
+
|
|
65
|
+
def get_order_by_sql_statement(self):
|
|
66
|
+
if self.struct.source_incremental_column is not None:
|
|
67
|
+
return f' order by "{self.struct.source_incremental_column}" asc'
|
|
68
|
+
else:
|
|
69
|
+
return ""
|
|
70
|
+
|
|
71
|
+
def get_limit_sql_statement(self):
|
|
72
|
+
if self.migrator_redshift_connector.env == LOCAL:
|
|
73
|
+
return f" TOP 100"
|
|
74
|
+
# return f""
|
|
75
|
+
else:
|
|
76
|
+
return f""
|
|
77
|
+
|
|
78
|
+
def get_sql_statement(self):
|
|
79
|
+
sql = f"""
|
|
80
|
+
select
|
|
81
|
+
{self.get_limit_sql_statement()}
|
|
82
|
+
{self.get_columns_source()}
|
|
83
|
+
from "{self.struct.source_schema}"."{self.struct.source_table}" NOLOCK
|
|
84
|
+
where 1=1
|
|
85
|
+
{self.get_incremental_statement()}
|
|
86
|
+
{self.get_order_by_sql_statement()}
|
|
87
|
+
"""
|
|
88
|
+
return sql
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from .PostgresReader import PostgresReader
|
|
2
|
+
from .SQLServerReader import SQLServerReader
|
|
2
3
|
from ..Types import POSTGRES, SQLSERVER
|
|
3
4
|
|
|
4
5
|
|
|
@@ -6,4 +7,4 @@ def factory(s3_credentials, struct, migrator_redshift_connector):
|
|
|
6
7
|
if migrator_redshift_connector.source_conn_type == POSTGRES:
|
|
7
8
|
return PostgresReader(s3_credentials, struct, migrator_redshift_connector)
|
|
8
9
|
elif migrator_redshift_connector.source_conn_type == SQLSERVER:
|
|
9
|
-
return
|
|
10
|
+
return SQLServerReader(s3_credentials, struct, migrator_redshift_connector)
|
|
@@ -22,6 +22,19 @@ class AdapterSourceTarget:
|
|
|
22
22
|
def __init__(self, struct):
|
|
23
23
|
self.struct = struct
|
|
24
24
|
|
|
25
|
+
def order_by_cdc(self, op, df):
|
|
26
|
+
if op == "U":
|
|
27
|
+
if "cdc_datetime" not in df.columns:
|
|
28
|
+
return df
|
|
29
|
+
else:
|
|
30
|
+
if df['cdc_datetime'].isnull().any():
|
|
31
|
+
return df
|
|
32
|
+
else:
|
|
33
|
+
df = df.sort_values('cdc_datetime', ascending=True)
|
|
34
|
+
return df
|
|
35
|
+
else:
|
|
36
|
+
return df
|
|
37
|
+
|
|
25
38
|
def convert_types(self, df):
|
|
26
39
|
for c in self.struct.columns:
|
|
27
40
|
case_target_type = {
|
|
@@ -33,8 +33,8 @@ class GenericWriter:
|
|
|
33
33
|
create temp table {self.temp_target_relation} as (
|
|
34
34
|
SELECT distinct a.* FROM {self.target_relation} as a
|
|
35
35
|
join (
|
|
36
|
-
SELECT {pk_columns}, count(*) FROM {self.target_relation}
|
|
37
|
-
group by {pk_columns} having count(*) > 1
|
|
36
|
+
SELECT "{pk_columns}", count(*) FROM {self.target_relation}
|
|
37
|
+
group by "{pk_columns}" having count(*) > 1
|
|
38
38
|
) as subselect
|
|
39
39
|
on 1=1
|
|
40
40
|
{self.create_statement_comparison_pk_columns('subselect', 'a')}
|
|
@@ -17,14 +17,13 @@ class WriterCDC(GenericWriter, WriterInterface):
|
|
|
17
17
|
df = self.get_op_rows(df, op=op)
|
|
18
18
|
adapter = AdapterSourceTarget(self.struct)
|
|
19
19
|
df = adapter.convert_types(df)
|
|
20
|
+
df = adapter.order_by_cdc(op, df)
|
|
20
21
|
df = adapter.transform_data(df)
|
|
21
22
|
df = adapter.equalize_number_columns(df)
|
|
22
23
|
|
|
23
24
|
if df.empty is False:
|
|
24
25
|
if op == "U":
|
|
25
|
-
df = df.drop_duplicates(
|
|
26
|
-
subset=self.struct.columns_upsert, keep="last"
|
|
27
|
-
)
|
|
26
|
+
df = df.drop_duplicates(subset=self.struct.columns_upsert, keep="last")
|
|
28
27
|
|
|
29
28
|
buffer = io.BytesIO()
|
|
30
29
|
df.to_csv(buffer, index=False)
|
|
@@ -43,6 +43,7 @@ maisaedu_poormans_dms/redshift_migration/Models/Struct.py
|
|
|
43
43
|
maisaedu_poormans_dms/redshift_migration/Models/__init__.py
|
|
44
44
|
maisaedu_poormans_dms/redshift_migration/Reader/GenericReader.py
|
|
45
45
|
maisaedu_poormans_dms/redshift_migration/Reader/PostgresReader.py
|
|
46
|
+
maisaedu_poormans_dms/redshift_migration/Reader/SQLServerReader.py
|
|
46
47
|
maisaedu_poormans_dms/redshift_migration/Reader/__init__.py
|
|
47
48
|
maisaedu_poormans_dms/redshift_migration/Services/AdapterSourceTarget.py
|
|
48
49
|
maisaedu_poormans_dms/redshift_migration/Services/ExtractionOperation.py
|
|
File without changes
|
{maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|