apache-airflow-providers-teradata 1.0.11__py3-none-any.whl → 2.0.0__py3-none-any.whl

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.

Potentially problematic release.


This version of apache-airflow-providers-teradata might be problematic. Click here for more details.

Files changed (24) hide show
  1. airflow/providers/teradata/LICENSE +253 -0
  2. airflow/providers/teradata/__init__.py +26 -1
  3. airflow/providers/teradata/get_provider_info.py +43 -24
  4. airflow/providers/teradata/hooks/teradata.py +202 -0
  5. airflow/providers/teradata/operators/teradata.py +64 -0
  6. airflow/providers/teradata/transfers/teradata_to_teradata.py +101 -0
  7. apache_airflow_providers_teradata-2.0.0.dist-info/METADATA +137 -0
  8. apache_airflow_providers_teradata-2.0.0.dist-info/RECORD +13 -0
  9. {apache_airflow_providers_teradata-1.0.11.dist-info → apache_airflow_providers_teradata-2.0.0.dist-info}/WHEEL +1 -2
  10. apache_airflow_providers_teradata-2.0.0.dist-info/entry_points.txt +3 -0
  11. airflow/providers/teradata/example_dags/example_execute_bteq.py +0 -51
  12. airflow/providers/teradata/example_dags/example_export_csv.py +0 -48
  13. airflow/providers/teradata/example_dags/example_load_csv.py +0 -69
  14. airflow/providers/teradata/hooks/ttu.py +0 -394
  15. airflow/providers/teradata/operators/bteq.py +0 -70
  16. airflow/providers/teradata/operators/fastexport.py +0 -77
  17. airflow/providers/teradata/operators/fastload.py +0 -105
  18. apache_airflow_providers_teradata-1.0.11.dist-info/AUTHORS.rst +0 -13
  19. apache_airflow_providers_teradata-1.0.11.dist-info/LICENSE +0 -22
  20. apache_airflow_providers_teradata-1.0.11.dist-info/METADATA +0 -53
  21. apache_airflow_providers_teradata-1.0.11.dist-info/RECORD +0 -19
  22. apache_airflow_providers_teradata-1.0.11.dist-info/entry_points.txt +0 -3
  23. apache_airflow_providers_teradata-1.0.11.dist-info/top_level.txt +0 -1
  24. /airflow/providers/teradata/{example_dags → transfers}/__init__.py +0 -0
@@ -1,394 +0,0 @@
1
- #
2
- # Licensed to the Apache Software Foundation (ASF) under one
3
- # or more contributor license agreements. See the NOTICE file
4
- # distributed with this work for additional information
5
- # regarding copyright ownership. The ASF licenses this file
6
- # to you under the Apache License, Version 2.0 (the
7
- # "License"); you may not use this file except in compliance
8
- # with the License. You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing,
13
- # software distributed under the License is distributed on an
14
- # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
- # KIND, either express or implied. See the License for the
16
- # specific language governing permissions and limitations
17
- # under the License.
18
-
19
- import os
20
- import uuid
21
- import subprocess
22
- from typing import Any, Dict, Iterator, List, Optional, Union
23
- from tempfile import gettempdir, NamedTemporaryFile, TemporaryDirectory
24
-
25
- from airflow import configuration as conf
26
- from airflow.exceptions import AirflowException
27
- from airflow.utils.log.logging_mixin import LoggingMixin
28
- from airflow.hooks.base import BaseHook
29
-
30
- class TtuHook(BaseHook, LoggingMixin):
31
- """
32
- Interact with Teradata using Teradata Tools and Utilities (TTU) binaries.
33
- Note: it is required that TTU previously installed and configured propertly.
34
-
35
- extras example: ``{"bteq_quit_zero":true, "bteq_session_encoding";"UTF8"}``
36
- """
37
- conn_name_attr = 'ttu_conn_id'
38
- default_conn_name = 'ttu_default'
39
- conn_type = 'ttu'
40
- hook_name = 'TTU'
41
-
42
- def __init__(self, ttu_conn_id: str = 'ttu_default') -> None:
43
- super().__init__()
44
- self.ttu_conn_id = ttu_conn_id
45
- self.conn = None
46
-
47
- def __enter__(self):
48
- return self
49
-
50
- def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
51
- if self.conn is not None:
52
- self.close_conn()
53
-
54
- def get_conn(self) -> dict:
55
- if not self.conn:
56
- connection = self.get_connection(self.ttu_conn_id)
57
- extras = connection.extra_dejson
58
- self.conn = dict(
59
- login=connection.login,
60
- password=connection.password,
61
- host=connection.host,
62
- ttu_log_folder=extras.get('ttu_log_folder', '/tmp'),
63
- console_output_encoding=extras.get('console_output_encoding', 'utf-8'),
64
- bteq_session_encoding=extras.get('bteq_session_encoding', 'ASCII'),
65
- bteq_output_width=extras.get('bteq_output_width', 65531),
66
- bteq_quit_zero=extras.get('bteq_quit_zero', False),
67
- sp = None
68
- )
69
- return self.conn
70
-
71
- def close_conn(self):
72
- """
73
- Closes the connection. An error will occur if the
74
- connection wasn't ever opened.
75
- """
76
- self.conn = None
77
-
78
- def execute_bteq(self, bteq, xcom_push_flag=False):
79
- """
80
- Executes BTEQ sentences using BTEQ binary.
81
- :param bteq: string of BTEQ sentences
82
- :param xcom_push_flag: Flag for pushing last line of BTEQ Log to XCom
83
- """
84
- conn = self.get_conn()
85
- self.log.info("Executing BTEQ sentences...")
86
- with TemporaryDirectory(prefix='airflowtmp_ttu_bteq_') as tmpdir:
87
- with NamedTemporaryFile(dir=tmpdir, mode='wb') as tmpfile:
88
- bteq_file = self._prepare_bteq_script(bteq,
89
- conn['host'],
90
- conn['login'],
91
- conn['password'],
92
- conn['bteq_output_width'],
93
- conn['bteq_session_encoding'],
94
- conn['bteq_quit_zero']
95
- )
96
- self.log.debug(bteq_file)
97
- tmpfile.write(bytes(bteq_file,'UTF8'))
98
- tmpfile.flush()
99
- tmpfile.seek(0)
100
-
101
- conn['sp'] = subprocess.Popen(['bteq'],
102
- stdin=tmpfile,
103
- stdout=subprocess.PIPE,
104
- stderr=subprocess.STDOUT,
105
- cwd=tmpdir,
106
- preexec_fn=os.setsid)
107
-
108
- line = ''
109
- failure_line = 'unknown reasons. Please see full BTEQ Output for more details.'
110
- self.log.info("Output:")
111
- for line in iter(conn['sp'].stdout.readline, b''):
112
- line = line.decode(conn['console_output_encoding']).strip()
113
- self.log.info(line)
114
- if "Failure" in line:
115
- #Just save the last failure
116
- failure_line = line
117
- conn['sp'].wait()
118
-
119
- self.log.info("BTEQ command exited with return code {0}".format(conn['sp'].returncode))
120
-
121
- if conn['sp'].returncode:
122
- raise AirflowException("BTEQ command exited with return code " + str(conn['sp'].returncode) + ' because of ' +
123
- failure_line)
124
- if xcom_push_flag:
125
- return line
126
-
127
- def execute_tdload(self, input_file, table, delimiter=';', working_database=None, encoding='UTF8', xcom_push_flag=False, raise_on_rows_error=False, raise_on_rows_duplicated=False, debug=False, max_sessions=1, restart_limit=0):
128
- """
129
- Load a CSV file to Teradata Table (previously created) using tdload binary.
130
- Note: You need to strip header of the CSV. tdload only accepts rows, not header.
131
- :param input_file : file to load
132
- :param table : output table
133
- :param delimeter : separator of the file to load
134
- :param encoding : encoding of the file to load
135
- :param working_database : teradata working database to use for staging data
136
- :param xcom_push_flag: Flag for pushing last line of BTEQ Log to XCom
137
- :raise_on_rows_error: if true, raise an error when found error loading some rows.
138
- :raise_on_rows_duplicated= if true, raise an error when found duplicated rows.
139
-
140
- """
141
- conn = self.get_conn()
142
- fload_out_path = conn['ttu_log_folder'] + '/tdload/out'
143
- if not os.path.exists(fload_out_path):
144
- self.log.debug('Creating directory ' + fload_out_path)
145
- os.makedirs(fload_out_path)
146
-
147
- fload_checkpoint_path = conn['ttu_log_folder'] + '/tdload/checkpoint'
148
- if not os.path.exists(fload_checkpoint_path):
149
- self.log.debug('Creating directory ' + fload_checkpoint_path)
150
- os.makedirs(fload_checkpoint_path)
151
- self.log.info('Loading file ' + input_file + ' into table ' + table + '')
152
- conn['sp'] = subprocess.Popen(self._prepare_tdload_command(
153
- input_file,
154
- conn['host'],
155
- conn['login'],
156
- conn['password'],
157
- encoding,
158
- table,
159
- delimiter,
160
- fload_out_path,
161
- fload_checkpoint_path,
162
- max_sessions,
163
- working_database,
164
- debug,
165
- restart_limit
166
- ),
167
- stdout=subprocess.PIPE, stderr=subprocess.STDOUT,preexec_fn=os.setsid)
168
- line = ''
169
- failure_line = 'unknown reasons. Please see full TPT FastLoad Output for more details.'
170
- rows_in_error_tables_line = 'Total Rows in Error Table'
171
- rows_duplicated_line = 'Total Duplicate Rows'
172
- rows_error=0
173
- rows_duplicated=0
174
- for line in iter(conn['sp'].stdout.readline, b''):
175
- line = line.decode(conn['console_output_encoding']).strip()
176
- self.log.info(line)
177
- if rows_in_error_tables_line in line:
178
- # check if we have error rows
179
- rows_error+=int(line.split(':')[-1].strip())
180
- if rows_duplicated_line in line:
181
- # check if we have duplicated rows
182
- rows_duplicated+=int(line.split(':')[-1].strip())
183
- if "error" in line:
184
- # get the last failure
185
- failure_line = line
186
-
187
- conn['sp'].wait()
188
- self.log.info("TPT FastLoad exited with "
189
- "return code {0}".format(conn['sp'].returncode))
190
-
191
- if conn['sp'].returncode:
192
- raise AirflowException("TPT FastLoad exited with return code " + str(conn['sp'].returncode) + ' because of ' +
193
- failure_line)
194
-
195
- if rows_error>0 and raise_on_rows_error:
196
- raise AirflowException("Failed because of errors loading rows (Rows with error: %s )" % rows_error)
197
-
198
- if rows_duplicated>0 and raise_on_rows_duplicated:
199
- raise AirflowException("Failed because of errors loading rows (Rows with error: %s )" % rows_error)
200
-
201
- if xcom_push_flag:
202
- return line
203
-
204
-
205
- def execute_tptexport(self, sql, output_file, delimiter = ';', encoding='UTF8', spool_mode='SPOOL', xcom_push_flag=False, double_quote_varchar=True, max_sessions=1,block_size=1048472):
206
- """
207
- Export a table from Teradata Table using tpt binary.
208
- Note: The exported CSV file does not contains header row
209
- :param file : file to load
210
- :param delimeter : separator of the file to load
211
- :param encoding : encoding of the file to load
212
- :param table : output table
213
- :param max_sessions : max sessions to use
214
- :param block_size : specifies the block size to use when returning data to the client. The minimum is 256 bytes. The default is 1048472 bytes. The maximum is 16775168 bytes.
215
- :param spool_mode : ref https://docs.teradata.com/reader/tRbhWsU75TDpkqzyEZReyA/2gbczYmS~PRXRVKD0Dngtg
216
- :param xcom_push_flag: flag for pushing last line of BTEQ Log to XCom
217
- :param double_quote_varchar: if true, replace quotes with escaping char for Teradata SQL in TPT
218
- """
219
- conn = self.get_conn()
220
- fexp_out_path = conn['ttu_log_folder'] + '/tbuild/logs'
221
- if not os.path.exists(fexp_out_path):
222
- self.log.debug('Creating directory ' + fexp_out_path)
223
- os.makedirs(fexp_out_path)
224
-
225
- fexp_checkpoint_path = conn['ttu_log_folder'] + '/tbuild/checkpoint'
226
- if not os.path.exists(fexp_checkpoint_path):
227
- self.log.debug('Creating directory ' + fexp_checkpoint_path)
228
- os.makedirs(fexp_checkpoint_path)
229
- if double_quote_varchar:
230
- sql = sql.replace("'", "''")
231
- self.log.info("""Exporting SQL '""" + sql + """' to file """ + output_file + """ using TPT Export""")
232
-
233
- with TemporaryDirectory(prefix='airflowtmp_ttu_tpt') as tmp_dir:
234
- with NamedTemporaryFile(dir=tmp_dir, prefix=uuid.uuid4().hex, mode='wb') as f:
235
- f.write(bytes(self._prepare_tpt_export_script(
236
- sql,
237
- output_file,
238
- encoding,
239
- delimiter,
240
- spool_mode,
241
- conn['host'],
242
- conn['login'],
243
- conn['password'],
244
- max_sessions,
245
- block_size,
246
- ), 'utf_8'))
247
- f.flush()
248
- fname = f.name
249
- self.log.debug("Temporary TPT Template "
250
- "location :{0}".format(fname))
251
- f.seek(0)
252
- conn['sp'] = subprocess.Popen(
253
- ['tbuild', '-f', fname, 'airflow' + '_tpt_' + uuid.uuid4().hex],
254
- stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
255
- preexec_fn=os.setsid)
256
-
257
- line = ''
258
- error_line = 'unknown reasons. Please see full TPT Output for more details.'
259
- for line in iter(conn['sp'].stdout.readline, b''):
260
- line = line.decode(conn['console_output_encoding']).strip()
261
- self.log.info(line)
262
- if "error" in line:
263
- #Just save the last error
264
- error_line = line
265
- conn['sp'].wait()
266
- self.log.info("tbuild command exited with "
267
- "return code {0}".format(conn['sp'].returncode))
268
- if conn['sp'].returncode:
269
- raise AirflowException("TPT command exited with return code " + str(conn['sp'].returncode) + ' because of ' +
270
- error_line)
271
-
272
- if xcom_push_flag:
273
- return line
274
-
275
- def on_kill(self):
276
- self.log.debug('Killing child process...')
277
- conn = self.get_conn()
278
- conn['sp'].kill()
279
-
280
- @staticmethod
281
- def _prepare_bteq_script(bteq_string, host, login, password, bteq_output_width, bteq_session_encoding, bteq_quit_zero) -> str:
282
- """
283
- Prepare a BTEQ file with connection parameters for executing SQL Sentences with BTEQ syntax.
284
- :param bteq_string : bteq sentences to execute
285
- :param host : Teradata Host
286
- :param login : username for login
287
- :param password : password for login
288
- :param bteq_output_width : width of BTEQ output in console
289
- :param bteq_session_encoding : session encoding. See offical teradata docs for possible values
290
- :param bteq_quit_zero : if True, force a .QUIT 0 sentence at the end of the sentences (forcing return code = 0)
291
- """
292
- bteq_list = [".LOGON {}/{},{};".format(host, login, password)]
293
- bteq_list += [".SET WIDTH " + str(bteq_output_width) + ";"]
294
- bteq_list += [".SET SESSION CHARSET '" + bteq_session_encoding + "';"]
295
- bteq_list += [bteq_string]
296
- if bteq_quit_zero:
297
- bteq_list += [".QUIT 0;"]
298
- bteq_list += [".LOGOFF;"]
299
- bteq_list += [".EXIT;"]
300
- return "\n".join(bteq_list)
301
-
302
- @staticmethod
303
- def _prepare_tdload_command(input_file, host, login, password, encoding, table, delimiter, log_path, checkpoint_path, max_sessions, working_database, debug, restart_limit, job_name= 'airflow_tdload') -> str:
304
- """
305
- Prepare a tdload file with connection parameters for loading data from file
306
- :param input_file : bteq sentences to execute
307
- :param host : Teradata Host
308
- :param login : username for login
309
- :param password : password for login
310
- :param encoding : width of BTEQ output in console
311
- :param table : table name. See offical teradata docs for possible values
312
- :param delimiter : file separator. See offical teradata docs for possible values
313
- :param log_path : path for command output log
314
- :param checkpoint_path : path for command checkpoint.
315
- :param max_sessions : how many sessions we use for loading data
316
- :param working_database : database for staging data
317
- :param job_name : job name
318
- """
319
- tdload_command = ['tdload']
320
- tdload_command += ['-f'] + [input_file]
321
- tdload_command += ['-u'] + [login]
322
- tdload_command += ['-p'] + [password]
323
- tdload_command += ['-h'] + [host]
324
- tdload_command += ['-c'] + [encoding]
325
- tdload_command += ['-t'] + [table]
326
- tdload_command += ['-d'] + [delimiter]
327
- tdload_command += ['-L'] + [log_path]
328
- tdload_command += ['-r'] + [checkpoint_path]
329
- tdload_command += ['-R'] + [str(restart_limit)]
330
- tdload_command += ['--TargetMaxSessions'] + [str(max_sessions)]
331
- if working_database:
332
- tdload_command += ['--TargetWorkingDatabase'] + [working_database]
333
- if debug:
334
- tdload_command += ['-x']
335
- tdload_command += [ "%s_%s" % (job_name, uuid.uuid4().hex) ] #Job Name
336
- return tdload_command
337
-
338
- @staticmethod
339
- def _prepare_tpt_export_script(sql, output_file, encoding, delimiter, spool_mode, host, login, password, max_sessions, block_size,job_name= 'airflow_tptexport') -> str:
340
- """
341
- Prepare a tpt script file with connection parameters for exporting data to CSV
342
- :param sql : SQL sentence to export
343
- :param output_file : path to output file
344
- :param encoding : encoding of exported CSV file (see teradata docs for possible value)
345
- :param delimiter : Delimiter for exported CSV file
346
- :param spool_mode : ref https://docs.teradata.com/reader/tRbhWsU75TDpkqzyEZReyA/2gbczYmS~PRXRVKD0Dngtg
347
- :param host : Teradata Host
348
- :param login : username for login
349
- :param password : password for login
350
- :param max_sessions : how many sessions we use for loading data
351
- :param block_size : specifies the block size to use when returning data to the client. The minimum is 256 bytes. The default is 1048472 bytes. The maximum is 16775168 bytes.
352
- :param job_name : job name
353
- """
354
- option_max_sessions = 'MaxSessions = {max_sessions},'.format(max_sessions=max_sessions)
355
- if max_sessions == -1:
356
- option_max_sessions = ''
357
- return '''
358
- USING CHARACTER SET {encoding}
359
- DEFINE JOB {job_name}
360
- (
361
- APPLY
362
- TO OPERATOR
363
- (
364
- $FILE_WRITER()
365
-
366
- ATTRIBUTES
367
- (
368
- FileName = '{filename}',
369
- Format = 'DELIMITED',
370
- OpenMode = 'Write',
371
- IndicatorMode = 'N',
372
- TextDelimiter = '{delimiter}'
373
- )
374
- )
375
- SELECT * FROM OPERATOR
376
- (
377
- $EXPORT()
378
-
379
- ATTRIBUTES
380
- (
381
- UserName = '{username}',
382
- UserPassword = '{password}',
383
- SelectStmt = '{sql}',
384
- TdpId = '{host}',
385
- {option_max_sessions}
386
- SpoolMode = '{spool_mode}',
387
- BlockSize = {block_size}
388
- )
389
- );
390
- );
391
- '''.format(filename=output_file, encoding=encoding, delimiter=delimiter, username=login,
392
- password=password, sql=sql, host=host, option_max_sessions=option_max_sessions, job_name = job_name, spool_mode=spool_mode,block_size=block_size)
393
-
394
-
@@ -1,70 +0,0 @@
1
- #
2
- # Licensed to the Apache Software Foundation (ASF) under one
3
- # or more contributor license agreements. See the NOTICE file
4
- # distributed with this work for additional information
5
- # regarding copyright ownership. The ASF licenses this file
6
- # to you under the Apache License, Version 2.0 (the
7
- # "License"); you may not use this file except in compliance
8
- # with the License. You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing,
13
- # software distributed under the License is distributed on an
14
- # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
- # KIND, either express or implied. See the License for the
16
- # specific language governing permissions and limitations
17
- # under the License.
18
- from typing import Iterable, Mapping, Optional, Union
19
-
20
- from airflow.models import BaseOperator
21
- from airflow.providers.teradata.hooks.ttu import TtuHook
22
- from airflow.utils.decorators import apply_defaults
23
-
24
- class BteqOperator(BaseOperator):
25
- """
26
- Executes BTEQ code in a specific Teradata database
27
-
28
- :param sql: the bteq code to be executed. (templated)
29
- :type sql: Can receive a str representing a sql statement,
30
- a list of str (sql statements), or reference to a template file.
31
- Template reference are recognized by str ending in '.sql'
32
- :param postgres_conn_id: reference to a specific postgres database
33
- :type postgres_conn_id: str
34
- :param autocommit: if True, each command is automatically committed.
35
- (default value: False)
36
- :type autocommit: bool
37
- :param parameters: (optional) the parameters to render the SQL query with.
38
- :type parameters: dict or iterable
39
- :param database: name of database which overwrite defined one in connection
40
- :type database: str
41
- """
42
-
43
- template_fields = ('sql',)
44
- template_ext = ('.sql', '.bteq',)
45
- ui_color = '#ff976d'
46
-
47
- @apply_defaults
48
- def __init__(
49
- self,
50
- *,
51
- bteq: str,
52
- xcom_push: bool = True,
53
- ttu_conn_id: str = 'ttu_default',
54
- **kwargs
55
- ) -> None:
56
- super().__init__(**kwargs)
57
- self.sql = bteq
58
- self._hook = None
59
- self.xcom_push = xcom_push
60
- self.ttu_conn_id = ttu_conn_id
61
-
62
- def execute(self, context):
63
- """
64
- Call execute_bteq method from TttuHook to run the provided BTEQ string
65
- """
66
- self._hook = TtuHook(ttu_conn_id=self.ttu_conn_id)
67
- self._hook.execute_bteq(self.sql, self.xcom_push)
68
-
69
- def on_kill(self):
70
- self._hook.on_kill()
@@ -1,77 +0,0 @@
1
- #
2
- # Licensed to the Apache Software Foundation (ASF) under one
3
- # or more contributor license agreements. See the NOTICE file
4
- # distributed with this work for additional information
5
- # regarding copyright ownership. The ASF licenses this file
6
- # to you under the Apache License, Version 2.0 (the
7
- # "License"); you may not use this file except in compliance
8
- # with the License. You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing,
13
- # software distributed under the License is distributed on an
14
- # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
- # KIND, either express or implied. See the License for the
16
- # specific language governing permissions and limitations
17
- # under the License.
18
- from typing import Iterable, Mapping, Optional, Union
19
-
20
- from airflow.models import BaseOperator
21
- from airflow.providers.teradata.hooks.ttu import TtuHook
22
- from airflow.utils.decorators import apply_defaults
23
-
24
- class FastExportOperator(BaseOperator):
25
- """
26
- Export a table from Teradata to csv file
27
- :param sql_select_stmt: Select statament to export
28
- :type sql_select_stmt: str
29
- :param output_file: output file to export
30
- :type output_file: str
31
- """
32
- template_fields = ('sql','output_file',)
33
- template_ext = ('.sql',)
34
- ui_color = '#a8e4b1'
35
-
36
- def __init__(
37
- self,
38
- *,
39
- sql_select_stmt: str,
40
- output_file: str,
41
- delimiter: str = ';',
42
- encoding: str = 'UTF8',
43
- spool_mode: str = 'SPOOL',
44
- xcom_push: bool = True,
45
- ttu_conn_id: str = 'ttu_default',
46
- max_sessions: Optional[int] = 1,
47
- block_size: Optional[int] = 1048472,
48
- **kwargs,
49
- ) -> None:
50
- super().__init__(**kwargs)
51
- self.sql = sql_select_stmt
52
- self.output_file = output_file
53
- self.delimiter = delimiter
54
- self.encoding = encoding
55
- self.spool_mode = spool_mode
56
- self.xcom_push = xcom_push
57
- self._hook = None
58
- self.ttu_conn_id = ttu_conn_id
59
- self.max_sessions = max_sessions
60
- self.block_size = block_size
61
-
62
- def execute(self, context):
63
- """
64
- Call the function
65
- """
66
- self._hook = TtuHook(ttu_conn_id=self.ttu_conn_id)
67
- self._hook.execute_tptexport(sql=self.sql,
68
- output_file=self.output_file,
69
- delimiter=self.delimiter,
70
- encoding=self.encoding,
71
- spool_mode=self.spool_mode,
72
- xcom_push_flag=self.xcom_push,
73
- max_sessions=self.max_sessions,
74
- block_size=self.block_size
75
- )
76
- def on_kill(self):
77
- self._hook.on_kill()
@@ -1,105 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
- #
15
- import logging
16
-
17
- from typing import Iterable, Mapping, Optional, Union
18
-
19
-
20
- from airflow.providers.teradata.hooks.ttu import TtuHook
21
- from airflow.models import BaseOperator
22
- from airflow.utils.decorators import apply_defaults
23
-
24
- log = logging.getLogger(__name__)
25
-
26
-
27
- class FastLoadOperator(BaseOperator):
28
- """
29
- Load a CSV file (without header) to Teradata Database Table
30
- :param input_file: output file to export
31
- :type input_file: str
32
- :param target_table: target table
33
- :type target_table: str
34
- :param delimiter: file delimiter
35
- :type delimiter: str
36
- :param working_database: database to create log tables
37
- :type working_database: str
38
- :param encoding: encoding of the file
39
- :type encoding: str
40
- :param xcom_push: True if return last log to xcom
41
- :type xcom_push: Bool
42
- """
43
- template_fields = ('input_file', 'target_table', 'preoperator_bteq',)
44
- template_ext = ('.sql', '.bteq',)
45
- ui_color = '#4aa3ba'
46
-
47
- @apply_defaults
48
- def __init__(
49
- self,
50
- *,
51
- input_file: str,
52
- target_table: str,
53
- working_database: str,
54
- delimiter: str = ';',
55
- encoding: str = 'UTF8',
56
- preoperator_bteq: Optional[str],
57
- raise_on_rows_error: bool = True,
58
- raise_on_rows_duplicated: bool = True,
59
- xcom_push: bool = True,
60
- ttu_conn_id: str = 'ttu_default',
61
- max_sessions: Optional[int] = 1,
62
- debug: Optional[bool] = False,
63
- **kwargs,
64
- ) -> None:
65
- super().__init__(**kwargs)
66
- self.input_file = input_file
67
- self.target_table = target_table
68
- self.working_database = working_database
69
- self.delimiter = delimiter
70
- self.encoding = encoding
71
- self.xcom_push = xcom_push
72
- self._hook = None
73
- self.ttu_conn_id = ttu_conn_id
74
- self.preoperator_bteq = preoperator_bteq
75
- self.raise_on_rows_error = raise_on_rows_error
76
- self.raise_on_rows_duplicated = raise_on_rows_duplicated
77
- self.max_sessions = max_sessions
78
- self.debug = debug
79
-
80
- def execute(self, context):
81
- """
82
- Call the executable from teradata
83
- """
84
- self._hook = TtuHook(ttu_conn_id=self.ttu_conn_id)
85
-
86
- if self.preoperator_bteq:
87
- logging.info('Executing preoperator BTEQ')
88
- self._hook.execute_bteq(self.preoperator_bteq, self.xcom_push)
89
-
90
-
91
- logging.info('Executing tdload command')
92
- self._hook.execute_tdload(
93
- input_file=self.input_file,
94
- table=self.target_table,
95
- working_database=self.working_database,
96
- delimiter=self.delimiter,
97
- encoding=self.encoding,
98
- xcom_push_flag=self.xcom_push,
99
- raise_on_rows_error=self.raise_on_rows_error,
100
- raise_on_rows_duplicated=self.raise_on_rows_duplicated,
101
- debug=self.debug,
102
- max_sessions=self.max_sessions
103
- )
104
- def on_kill(self):
105
- self._hook.on_kill()
@@ -1,13 +0,0 @@
1
- =======
2
- Credits
3
- =======
4
-
5
- Development Lead
6
- ----------------
7
-
8
- * Felipe Lolas <flolas@icloud.com>
9
-
10
- Contributors
11
- ------------
12
-
13
- None yet. Why not be the first?
@@ -1,22 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2021, Felipe Lolas
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
22
-