maisaedu-poormans-dms 1.1.77__tar.gz → 1.1.79__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 (47) hide show
  1. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/PKG-INFO +1 -1
  2. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/redshift_migration/Connector.py +20 -5
  3. maisaedu-poormans-dms-1.1.79/maisaedu_poormans_dms/redshift_migration/Contracts/ReaderInterface.py +22 -0
  4. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/redshift_migration/MigratorRedshift.py +4 -4
  5. maisaedu-poormans-dms-1.1.77/maisaedu_poormans_dms/redshift_migration/Reader.py → maisaedu-poormans-dms-1.1.79/maisaedu_poormans_dms/redshift_migration/Reader/GenericReader.py +8 -81
  6. maisaedu-poormans-dms-1.1.79/maisaedu_poormans_dms/redshift_migration/Reader/PostgresReader.py +82 -0
  7. maisaedu-poormans-dms-1.1.79/maisaedu_poormans_dms/redshift_migration/Reader/__init__.py +9 -0
  8. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/redshift_migration/Types.py +2 -0
  9. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms.egg-info/PKG-INFO +1 -1
  10. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms.egg-info/SOURCES.txt +4 -1
  11. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/setup.py +1 -1
  12. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/LICENSE +0 -0
  13. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/__init__.py +0 -0
  14. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/postgres_migration/Contracts/MigratorInterface.py +0 -0
  15. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/postgres_migration/Contracts/MigratorRowInterface.py +0 -0
  16. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/postgres_migration/Contracts/MigratorRowReaderInterface.py +0 -0
  17. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/postgres_migration/Contracts/MigratorRowWriterInterface.py +0 -0
  18. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/postgres_migration/Contracts/MigratorTableInterface.py +0 -0
  19. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/postgres_migration/Contracts/__init__.py +0 -0
  20. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/postgres_migration/Migrator.py +0 -0
  21. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/postgres_migration/MigratorRow/MigratorRow.py +0 -0
  22. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/postgres_migration/MigratorRow/Reader.py +0 -0
  23. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/postgres_migration/MigratorRow/Writer.py +0 -0
  24. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/postgres_migration/MigratorRow/__init__.py +0 -0
  25. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/postgres_migration/MigratorTable.py +0 -0
  26. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/postgres_migration/__init__.py +0 -0
  27. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/redshift_migration/Contracts/WriterInterface.py +0 -0
  28. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/redshift_migration/Contracts/__init__.py +0 -0
  29. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/redshift_migration/Logger.py +0 -0
  30. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/redshift_migration/Models/ExtractionOperation.py +0 -0
  31. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/redshift_migration/Models/Struct.py +0 -0
  32. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/redshift_migration/Models/__init__.py +0 -0
  33. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/redshift_migration/Services/AdapterSourceTarget.py +0 -0
  34. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/redshift_migration/Services/ExtractionOperation.py +0 -0
  35. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/redshift_migration/Services/RelationExtraction.py +0 -0
  36. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/redshift_migration/Services/Struct.py +0 -0
  37. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/redshift_migration/Services/__init__.py +0 -0
  38. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/redshift_migration/Writer/GenericWriter.py +0 -0
  39. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/redshift_migration/Writer/WriterCDC.py +0 -0
  40. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/redshift_migration/Writer/WriterNonCDC.py +0 -0
  41. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/redshift_migration/Writer/__init__.py +0 -0
  42. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/redshift_migration/__init__.py +0 -0
  43. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms/sql_server_migration.py +0 -0
  44. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms.egg-info/dependency_links.txt +0 -0
  45. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms.egg-info/requires.txt +0 -0
  46. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/maisaedu_poormans_dms.egg-info/top_level.txt +0 -0
  47. {maisaedu-poormans-dms-1.1.77 → maisaedu-poormans-dms-1.1.79}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: maisaedu-poormans-dms
3
- Version: 1.1.77
3
+ Version: 1.1.79
4
4
  Summary: A library for making database migration tasks, for +A Education
5
5
  Home-page: UNKNOWN
6
6
  Author: A+ Educação
@@ -3,17 +3,28 @@ import psycopg2
3
3
  from sqlalchemy import create_engine
4
4
 
5
5
  from maisaedu_utilities_prefect.dw import get_red_credentials
6
- from .Types import DEV, LOCAL, get_iam_role
6
+ from .Types import DEV, LOCAL, POSTGRES, SQLSERVER, get_iam_role
7
7
 
8
8
 
9
9
  class Connector:
10
10
  def __init__(self, env, s3_credentials, source_credentials, target_credentials):
11
11
  self.source_credentials = source_credentials
12
+ self.__set_source_conn_type()
12
13
  self.target_credentials = target_credentials
13
14
  self.s3_credentials = s3_credentials
14
15
  self.env = env
15
16
  self.iam_role = get_iam_role(env)
16
17
 
18
+ def __set_source_conn_type(self):
19
+ if self.source_credentials is None:
20
+ self.source_conn_type = None
21
+ else:
22
+ if 'type' not in self.source_credentials:
23
+ self.source_conn_type = POSTGRES
24
+ else:
25
+ self.source_conn_type = self.source_credentials['type']
26
+
27
+
17
28
  def connect_target(self):
18
29
  if self.target_credentials is None:
19
30
  if self.env == LOCAL:
@@ -48,10 +59,14 @@ class Connector:
48
59
  self.s3_session = session.resource("s3")
49
60
 
50
61
  def connect_source(self):
51
- engine = create_engine(
52
- f"postgresql+psycopg2://{self.source_credentials['user']}:{self.source_credentials['password']}@{self.source_credentials['host']}:{self.source_credentials['port']}/{self.source_credentials['database']}"
53
- )
54
- self.source_conn = engine.connect().execution_options(stream_results=True)
62
+ if self.source_conn_type == POSTGRES:
63
+ engine = create_engine(
64
+ f"postgresql+psycopg2://{self.source_credentials['user']}:{self.source_credentials['password']}@{self.source_credentials['host']}:{self.source_credentials['port']}/{self.source_credentials['database']}"
65
+ )
66
+ self.source_conn = engine.connect().execution_options(stream_results=True)
67
+ elif self.source_conn_type == SQLSERVER:
68
+ print("SQLSERVER")
69
+ # TODO
55
70
 
56
71
  def close_source(self):
57
72
  self.source_conn.close()
@@ -0,0 +1,22 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+ class ReaderInterface(ABC):
4
+ @abstractmethod
5
+ def get_incremental_statement(self) -> str:
6
+ pass
7
+
8
+ @abstractmethod
9
+ def get_columns_source(self) -> str:
10
+ pass
11
+
12
+ @abstractmethod
13
+ def get_order_by_sql_statement(self) -> str:
14
+ pass
15
+
16
+ @abstractmethod
17
+ def get_limit_sql_statement(self) -> str:
18
+ pass
19
+
20
+ @abstractmethod
21
+ def get_sql_statement(self) -> str:
22
+ pass
@@ -1,7 +1,7 @@
1
1
  from .Connector import Connector
2
- from .Reader import Reader
2
+ from .Reader import factory as reader_factory
3
3
  from .Logger import Logger
4
- from .Writer import factory
4
+ from .Writer import factory as writer_factory
5
5
  from .Services.Struct import Struct
6
6
  from .Services.ExtractionOperation import ExtractionOperation
7
7
  from .Services.RelationExtraction import RelationExtraction
@@ -38,7 +38,7 @@ class MigratorRedshift:
38
38
 
39
39
  self.migrator_redshift_connector.connect_target()
40
40
 
41
- self.migrator_redshift_reader = Reader(
41
+ self.migrator_redshift_reader = reader_factory(
42
42
  s3_credentials=s3_credentials,
43
43
  struct=struct,
44
44
  migrator_redshift_connector=self.migrator_redshift_connector,
@@ -150,7 +150,7 @@ class MigratorRedshift:
150
150
  self.__check_target_table_has_data()
151
151
  update_by_cdc = self.__check_table_will_be_updated_by_cdc(load_option)
152
152
 
153
- self.migrator_redshift_writer = factory(
153
+ self.migrator_redshift_writer = writer_factory(
154
154
  env=self.env,
155
155
  update_by_cdc=update_by_cdc,
156
156
  struct=self.struct,
@@ -2,7 +2,7 @@ import io
2
2
  import threading
3
3
  import pandas as pd
4
4
  from datetime import datetime
5
- from .Types import (
5
+ from ..Types import (
6
6
  target_type_is_numeric,
7
7
  LOCAL,
8
8
  FULL,
@@ -12,91 +12,18 @@ from .Types import (
12
12
  PREFECT,
13
13
  S3,
14
14
  )
15
- from .Services.ExtractionOperation import ExtractionOperation
16
- from .Services.AdapterSourceTarget import AdapterSourceTarget
17
- from .Models.ExtractionOperation import ExtractionOperation as ExtractionOperationModel
15
+ from ..Services.ExtractionOperation import ExtractionOperation
16
+ from ..Services.AdapterSourceTarget import AdapterSourceTarget
17
+ from ..Models.ExtractionOperation import ExtractionOperation as ExtractionOperationModel
18
18
 
19
19
 
20
- class Reader:
20
+ class GenericReader:
21
21
  def __init__(self, s3_credentials, struct, migrator_redshift_connector):
22
22
  self.struct = struct
23
23
  self.s3_credentials = s3_credentials
24
24
  self.migrator_redshift_connector = migrator_redshift_connector
25
25
 
26
- def get_incremental_statement(self):
27
- if (
28
- (
29
- self.struct.source_incremental_column is not None
30
- and self.struct.target_incremental_column is not None
31
- and (self.load_option is None)
32
- ) or (self.load_option == INCREMENTAL)
33
- ):
34
- sql = f"""
35
- select max("{self.struct.target_incremental_column}") as max_value
36
- from "{self.struct.target_schema}"."{self.struct.target_table}"
37
- """
38
-
39
- cursor = self.migrator_redshift_connector.target_conn.cursor()
40
-
41
- cursor.execute(sql)
42
- result = cursor.fetchall()
43
-
44
- if len(result) == 0 or result[0][0] is None:
45
- sql_return = ""
46
- self.load_option = FULL
47
- else:
48
- for c in self.struct.columns:
49
- if c["target_name"] == self.struct.target_incremental_column:
50
- target_type = c["target_type"]
51
-
52
- if target_type_is_numeric(target_type):
53
- sql_return = f'and "{self.struct.source_incremental_column}" > {result[0][0]}'
54
- else:
55
- if (
56
- self.struct.incremental_interval_delta is None
57
- or self.struct.incremental_interval_delta == ""
58
- ):
59
- sql_return = f"and \"{self.struct.source_incremental_column}\" > '{result[0][0]}'"
60
- else:
61
- sql_return = f"and \"{self.struct.source_incremental_column}\" >= '{result[0][0]}'::timestamp - interval '{self.struct.incremental_interval_delta}'"
62
-
63
- self.load_option = INCREMENTAL
64
-
65
- cursor.close()
66
-
67
- return sql_return
68
- else:
69
- if (self.load_option is None):
70
- self.load_option = FULL
71
- return ""
72
-
73
- def get_columns_source(self):
74
- return " * "
75
-
76
- def get_order_by_sql_statement(self):
77
- if self.struct.source_incremental_column is not None:
78
- return f' order by "{self.struct.source_incremental_column}" asc'
79
- else:
80
- return ""
81
-
82
- def get_limit_sql_statement(self):
83
- if self.migrator_redshift_connector.env == LOCAL:
84
- return f" limit 100"
85
- else:
86
- return f""
87
-
88
- def get_sql_statement(self):
89
- sql = f"""
90
- select {self.get_columns_source()}
91
- from "{self.struct.source_schema}"."{self.struct.source_table}"
92
- where 1=1
93
- {self.get_incremental_statement()}
94
- {self.get_order_by_sql_statement()}
95
- {self.get_limit_sql_statement()}
96
- """
97
- return sql
98
-
99
- def save_on_bucket(self, df, path_file, format="parquet"):
26
+ def __save_on_bucket(self, df, path_file, format="parquet"):
100
27
  buffer = io.BytesIO()
101
28
 
102
29
  if format == "csv":
@@ -116,13 +43,13 @@ class Reader:
116
43
 
117
44
  chunk_df_s3 = adapter.transform_data(chunk_df_s3, target_save=S3)
118
45
 
119
- self.save_on_bucket(chunk_df_s3, path_file)
46
+ self.__save_on_bucket(chunk_df_s3, path_file)
120
47
 
121
48
  chunk_df = adapter.convert_types(chunk_df)
122
49
  chunk_df = adapter.transform_data(chunk_df)
123
50
  chunk_df = adapter.equalize_number_columns(chunk_df)
124
51
 
125
- self.save_on_bucket(chunk_df, path_file_tmp, format="csv")
52
+ self.__save_on_bucket(chunk_df, path_file_tmp, format="csv")
126
53
 
127
54
  def save_data_to_s3(self, load_option=None):
128
55
  self.load_option = load_option
@@ -0,0 +1,82 @@
1
+ from ..Types import (
2
+ target_type_is_numeric,
3
+ LOCAL,
4
+ FULL,
5
+ INCREMENTAL,
6
+ )
7
+ from .GenericReader import GenericReader
8
+ from ..Contracts.ReaderInterface import ReaderInterface
9
+
10
+ class PostgresReader(GenericReader, ReaderInterface):
11
+ def get_incremental_statement(self):
12
+ if (
13
+ (
14
+ self.struct.source_incremental_column is not None
15
+ and self.struct.target_incremental_column is not None
16
+ and (self.load_option is None)
17
+ ) or (self.load_option == INCREMENTAL)
18
+ ):
19
+ sql = f"""
20
+ select max("{self.struct.target_incremental_column}") as max_value
21
+ from "{self.struct.target_schema}"."{self.struct.target_table}"
22
+ """
23
+
24
+ cursor = self.migrator_redshift_connector.target_conn.cursor()
25
+
26
+ cursor.execute(sql)
27
+ result = cursor.fetchall()
28
+
29
+ if len(result) == 0 or result[0][0] is None:
30
+ sql_return = ""
31
+ self.load_option = FULL
32
+ else:
33
+ for c in self.struct.columns:
34
+ if c["target_name"] == self.struct.target_incremental_column:
35
+ target_type = c["target_type"]
36
+
37
+ if target_type_is_numeric(target_type):
38
+ sql_return = f'and "{self.struct.source_incremental_column}" > {result[0][0]}'
39
+ else:
40
+ if (
41
+ self.struct.incremental_interval_delta is None
42
+ or self.struct.incremental_interval_delta == ""
43
+ ):
44
+ sql_return = f"and \"{self.struct.source_incremental_column}\" > '{result[0][0]}'"
45
+ else:
46
+ sql_return = f"and \"{self.struct.source_incremental_column}\" >= '{result[0][0]}'::timestamp - interval '{self.struct.incremental_interval_delta}'"
47
+
48
+ self.load_option = INCREMENTAL
49
+
50
+ cursor.close()
51
+
52
+ return sql_return
53
+ else:
54
+ if (self.load_option is None):
55
+ self.load_option = FULL
56
+ return ""
57
+
58
+ def get_columns_source(self):
59
+ return " * "
60
+
61
+ def get_order_by_sql_statement(self):
62
+ if self.struct.source_incremental_column is not None:
63
+ return f' order by "{self.struct.source_incremental_column}" asc'
64
+ else:
65
+ return ""
66
+
67
+ def get_limit_sql_statement(self):
68
+ if self.migrator_redshift_connector.env == LOCAL:
69
+ return f" limit 100"
70
+ else:
71
+ return f""
72
+
73
+ def get_sql_statement(self):
74
+ sql = f"""
75
+ select {self.get_columns_source()}
76
+ from "{self.struct.source_schema}"."{self.struct.source_table}"
77
+ where 1=1
78
+ {self.get_incremental_statement()}
79
+ {self.get_order_by_sql_statement()}
80
+ {self.get_limit_sql_statement()}
81
+ """
82
+ return sql
@@ -0,0 +1,9 @@
1
+ from .PostgresReader import PostgresReader
2
+ from ..Types import POSTGRES, SQLSERVER
3
+
4
+
5
+ def factory(s3_credentials, struct, migrator_redshift_connector):
6
+ if migrator_redshift_connector.source_conn_type == POSTGRES:
7
+ return PostgresReader(s3_credentials, struct, migrator_redshift_connector)
8
+ elif migrator_redshift_connector.source_conn_type == SQLSERVER:
9
+ return None
@@ -16,6 +16,8 @@ SAVED_REDSHIFT = "saved-redshift"
16
16
 
17
17
  S3 = "s3"
18
18
  REDSHIFT = "redshift"
19
+ POSTGRES = "postgres"
20
+ SQLSERVER = "sqlserver"
19
21
 
20
22
  MAX_VARCHAR_LENGTH = 60000
21
23
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: maisaedu-poormans-dms
3
- Version: 1.1.77
3
+ Version: 1.1.79
4
4
  Summary: A library for making database migration tasks, for +A Education
5
5
  Home-page: UNKNOWN
6
6
  Author: A+ Educação
@@ -23,14 +23,17 @@ maisaedu_poormans_dms/postgres_migration/MigratorRow/__init__.py
23
23
  maisaedu_poormans_dms/redshift_migration/Connector.py
24
24
  maisaedu_poormans_dms/redshift_migration/Logger.py
25
25
  maisaedu_poormans_dms/redshift_migration/MigratorRedshift.py
26
- maisaedu_poormans_dms/redshift_migration/Reader.py
27
26
  maisaedu_poormans_dms/redshift_migration/Types.py
28
27
  maisaedu_poormans_dms/redshift_migration/__init__.py
28
+ maisaedu_poormans_dms/redshift_migration/Contracts/ReaderInterface.py
29
29
  maisaedu_poormans_dms/redshift_migration/Contracts/WriterInterface.py
30
30
  maisaedu_poormans_dms/redshift_migration/Contracts/__init__.py
31
31
  maisaedu_poormans_dms/redshift_migration/Models/ExtractionOperation.py
32
32
  maisaedu_poormans_dms/redshift_migration/Models/Struct.py
33
33
  maisaedu_poormans_dms/redshift_migration/Models/__init__.py
34
+ maisaedu_poormans_dms/redshift_migration/Reader/GenericReader.py
35
+ maisaedu_poormans_dms/redshift_migration/Reader/PostgresReader.py
36
+ maisaedu_poormans_dms/redshift_migration/Reader/__init__.py
34
37
  maisaedu_poormans_dms/redshift_migration/Services/AdapterSourceTarget.py
35
38
  maisaedu_poormans_dms/redshift_migration/Services/ExtractionOperation.py
36
39
  maisaedu_poormans_dms/redshift_migration/Services/RelationExtraction.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.77",
5
+ version="1.1.79",
6
6
  description="A library for making database migration tasks, for +A Education",
7
7
  license="MIT License",
8
8
  author="A+ Educação",