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.
Files changed (58) hide show
  1. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/PKG-INFO +1 -1
  2. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Connector.py +4 -2
  3. maisaedu-poormans-dms-1.1.90/maisaedu_poormans_dms/redshift_migration/Reader/SQLServerReader.py +88 -0
  4. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Reader/__init__.py +2 -1
  5. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Services/AdapterSourceTarget.py +13 -0
  6. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Writer/GenericWriter.py +2 -2
  7. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Writer/WriterCDC.py +2 -3
  8. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms.egg-info/PKG-INFO +1 -1
  9. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms.egg-info/SOURCES.txt +1 -0
  10. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/setup.py +1 -1
  11. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/LICENSE +0 -0
  12. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/__init__.py +0 -0
  13. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/postgres_migration/Contracts/MigratorInterface.py +0 -0
  14. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/postgres_migration/Contracts/MigratorRowInterface.py +0 -0
  15. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/postgres_migration/Contracts/MigratorRowReaderInterface.py +0 -0
  16. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/postgres_migration/Contracts/MigratorRowWriterInterface.py +0 -0
  17. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/postgres_migration/Contracts/MigratorTableInterface.py +0 -0
  18. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/postgres_migration/Contracts/__init__.py +0 -0
  19. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/postgres_migration/Migrator.py +0 -0
  20. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/postgres_migration/MigratorRow/MigratorRow.py +0 -0
  21. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/postgres_migration/MigratorRow/Reader.py +0 -0
  22. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/postgres_migration/MigratorRow/Writer.py +0 -0
  23. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/postgres_migration/MigratorRow/__init__.py +0 -0
  24. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/postgres_migration/MigratorTable.py +0 -0
  25. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/postgres_migration/__init__.py +0 -0
  26. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_dynamo_migration/Connector.py +0 -0
  27. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_dynamo_migration/DynamoReplicator.py +0 -0
  28. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_dynamo_migration/Writer/WriterCDC.py +0 -0
  29. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_dynamo_migration/Writer/WriterFull.py +0 -0
  30. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_dynamo_migration/Writer/__init__.py +0 -0
  31. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_dynamo_migration/__init__.py +0 -0
  32. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_dynamo_migration/models/Struct.py +0 -0
  33. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_dynamo_migration/models/__init__.py +0 -0
  34. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_dynamo_migration/services/Struct.py +0 -0
  35. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_dynamo_migration/services/__init__.py +0 -0
  36. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Contracts/ReaderInterface.py +0 -0
  37. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Contracts/WriterInterface.py +0 -0
  38. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Contracts/__init__.py +0 -0
  39. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Logger.py +0 -0
  40. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/MigratorRedshift.py +0 -0
  41. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Models/ExtractionOperation.py +0 -0
  42. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Models/Struct.py +0 -0
  43. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Models/__init__.py +0 -0
  44. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Reader/GenericReader.py +0 -0
  45. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Reader/PostgresReader.py +0 -0
  46. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Services/ExtractionOperation.py +0 -0
  47. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Services/RelationExtraction.py +0 -0
  48. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Services/Struct.py +0 -0
  49. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Services/__init__.py +0 -0
  50. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Types.py +0 -0
  51. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Writer/WriterNonCDC.py +0 -0
  52. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/Writer/__init__.py +0 -0
  53. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/redshift_migration/__init__.py +0 -0
  54. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms/sql_server_migration.py +0 -0
  55. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms.egg-info/dependency_links.txt +0 -0
  56. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms.egg-info/requires.txt +0 -0
  57. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/maisaedu_poormans_dms.egg-info/top_level.txt +0 -0
  58. {maisaedu-poormans-dms-1.1.88 → maisaedu-poormans-dms-1.1.90}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: maisaedu-poormans-dms
3
- Version: 1.1.88
3
+ Version: 1.1.90
4
4
  Summary: A library for making database migration tasks, for +A Education
5
5
  Home-page: UNKNOWN
6
6
  Author: A+ Educação
@@ -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
- print("SQLSERVER")
69
- # TODO
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()
@@ -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 None
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)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: maisaedu-poormans-dms
3
- Version: 1.1.88
3
+ Version: 1.1.90
4
4
  Summary: A library for making database migration tasks, for +A Education
5
5
  Home-page: UNKNOWN
6
6
  Author: A+ Educação
@@ -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
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="maisaedu-poormans-dms",
5
- version="1.1.88",
5
+ version="1.1.90",
6
6
  description="A library for making database migration tasks, for +A Education",
7
7
  license="MIT License",
8
8
  author="A+ Educação",