luxorasap 0.2.8__py3-none-any.whl → 0.2.10__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.
- luxorasap/__init__.py +1 -1
- luxorasap/datareader/core.py +57 -52
- luxorasap/ingest/cloud/__init__.py +38 -16
- luxorasap/utils/storage/change_tracker.py +0 -51
- {luxorasap-0.2.8.dist-info → luxorasap-0.2.10.dist-info}/METADATA +1 -1
- {luxorasap-0.2.8.dist-info → luxorasap-0.2.10.dist-info}/RECORD +9 -9
- {luxorasap-0.2.8.dist-info → luxorasap-0.2.10.dist-info}/WHEEL +0 -0
- {luxorasap-0.2.8.dist-info → luxorasap-0.2.10.dist-info}/entry_points.txt +0 -0
- {luxorasap-0.2.8.dist-info → luxorasap-0.2.10.dist-info}/top_level.txt +0 -0
luxorasap/__init__.py
CHANGED
|
@@ -13,7 +13,7 @@ from types import ModuleType
|
|
|
13
13
|
try:
|
|
14
14
|
__version__: str = metadata.version(__name__)
|
|
15
15
|
except metadata.PackageNotFoundError: # editable install
|
|
16
|
-
__version__ = "0.2.
|
|
16
|
+
__version__ = "0.2.10"
|
|
17
17
|
|
|
18
18
|
# ─── Lazy loader ─────────────────────────────────────────────────
|
|
19
19
|
def __getattr__(name: str) -> ModuleType:
|
luxorasap/datareader/core.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import pandas as pd
|
|
3
3
|
import datetime as dt
|
|
4
4
|
from datetime import timezone
|
|
5
|
-
|
|
5
|
+
import logging
|
|
6
6
|
import os, sys
|
|
7
7
|
import time
|
|
8
8
|
import numpy as np
|
|
@@ -77,7 +77,7 @@ class LuxorQuery:
|
|
|
77
77
|
return file_last_update > self.tables_in_use[table_name]["update_time"]
|
|
78
78
|
|
|
79
79
|
except:
|
|
80
|
-
|
|
80
|
+
logging.info(f"Arquivo <{file_path}> não encontrado.")
|
|
81
81
|
|
|
82
82
|
return False
|
|
83
83
|
|
|
@@ -85,7 +85,7 @@ class LuxorQuery:
|
|
|
85
85
|
def __get_tickers_bbg(self):
|
|
86
86
|
# Deprecated.
|
|
87
87
|
# Criado apenas para manter compatibilidade
|
|
88
|
-
|
|
88
|
+
logging.info("Acesso direto a tabela 'bbg_ticker' sera descontinuado.\nAo inves disso, pegue os valores unicos de asset[Ticker_BBG]")
|
|
89
89
|
return pd.DataFrame(self.get_table("assets")["Ticker_BBG"].unique())
|
|
90
90
|
|
|
91
91
|
|
|
@@ -107,7 +107,8 @@ class LuxorQuery:
|
|
|
107
107
|
return tables
|
|
108
108
|
|
|
109
109
|
|
|
110
|
-
def get_table(self, table_name, index=False, index_name="index", dtypes_override={}, force_reload=False,
|
|
110
|
+
def get_table(self, table_name, index=False, index_name="index", dtypes_override={}, force_reload=False,
|
|
111
|
+
drop_last_updated_columns=True, auto_convert_mapped_types=True):
|
|
111
112
|
"""
|
|
112
113
|
Retorna uma copia do DataFrame do 'table_name' correspondente. Se não estiver disponivel,
|
|
113
114
|
retorna None.
|
|
@@ -143,9 +144,10 @@ class LuxorQuery:
|
|
|
143
144
|
return self.tables_in_use[table_name]["table_data"]
|
|
144
145
|
|
|
145
146
|
|
|
146
|
-
table_data = self.__load_table(table_name, index=index, index_name=index_name, dtypes_override=dtypes_override
|
|
147
|
+
table_data = self.__load_table(table_name, index=index, index_name=index_name, dtypes_override=dtypes_override,
|
|
148
|
+
auto_convert_mapped_types=auto_convert_mapped_types)
|
|
147
149
|
|
|
148
|
-
if drop_last_updated_columns:
|
|
150
|
+
if (table_data is not None) and drop_last_updated_columns:
|
|
149
151
|
if "Last_Updated" in table_data.columns:
|
|
150
152
|
return table_data.drop(columns=["Last_Updated"])
|
|
151
153
|
|
|
@@ -153,7 +155,7 @@ class LuxorQuery:
|
|
|
153
155
|
|
|
154
156
|
|
|
155
157
|
|
|
156
|
-
def __load_table(self, table_name, index=False, index_name="index", dtypes_override={}):
|
|
158
|
+
def __load_table(self, table_name, index=False, index_name="index", dtypes_override={}, auto_convert_mapped_types=True):
|
|
157
159
|
|
|
158
160
|
def __load_parquet(table_name):
|
|
159
161
|
table_path = f"{self.blob_directory}/{table_name}.parquet"#self.tables_path/"parquet"/f"{table_name}.parquet"
|
|
@@ -165,13 +167,16 @@ class LuxorQuery:
|
|
|
165
167
|
table_data, blob_read_success = self.blob_client.read_df(table_path)#__read_blob_parquet(table_name)
|
|
166
168
|
|
|
167
169
|
if not blob_read_success:
|
|
168
|
-
|
|
170
|
+
logging.info(f"Não foi possível carregar a tabela '{table_name}' do blob.")
|
|
169
171
|
#print("--> Onedrive fallback.")
|
|
170
172
|
#table_data = pd.read_parquet(table_path,engine="fastparquet")
|
|
171
173
|
update_time = self.blob_client.get_df_update_time(table_path)
|
|
172
174
|
|
|
173
175
|
assert(table_data is not None)
|
|
174
176
|
|
|
177
|
+
if not auto_convert_mapped_types:
|
|
178
|
+
return table_data, table_path, update_time
|
|
179
|
+
|
|
175
180
|
table_columns = set(table_data.columns)
|
|
176
181
|
|
|
177
182
|
float_dtypes = {"Last_Price", "Price", "px_last", "Quota", "#", "Avg_price", "Variation", "Variation_tot",
|
|
@@ -200,9 +205,9 @@ class LuxorQuery:
|
|
|
200
205
|
for col in table_columns.intersection(float_dtypes):
|
|
201
206
|
table_data[col] = table_data[col].astype(float)
|
|
202
207
|
except :
|
|
203
|
-
|
|
204
|
-
#
|
|
205
|
-
#
|
|
208
|
+
logging.info(f"Ao carregar tabela '{table_name}', nao foi possivel converter dados da coluna {col} para float.")
|
|
209
|
+
#logging.info(f"Colunas com erro: {table_columns.intersection(float_dtypes)}")
|
|
210
|
+
#logging.info(f"Colunas disponiveis: {table_columns}")
|
|
206
211
|
#print(table_data.dtypes)
|
|
207
212
|
|
|
208
213
|
raise ValueError(f"Erro ao converter colunas para float na tabela '{table_name}'.")
|
|
@@ -212,7 +217,7 @@ class LuxorQuery:
|
|
|
212
217
|
cols_to_format = list(set(table_data.columns) - {"Date", "Fund"})
|
|
213
218
|
table_data[cols_to_format] = table_data[cols_to_format].astype(float)
|
|
214
219
|
except ValueError:
|
|
215
|
-
|
|
220
|
+
logging.info("Ao carregar tabela 'hist_px_last', nao foi possivel converter dados para float.")
|
|
216
221
|
|
|
217
222
|
for col in table_columns.intersection(date_dtypes):
|
|
218
223
|
try:
|
|
@@ -227,7 +232,7 @@ class LuxorQuery:
|
|
|
227
232
|
.replace("false", "").replace("falso", "")
|
|
228
233
|
.replace("0", "").replace("nan", "").astype(bool))
|
|
229
234
|
except Exception:
|
|
230
|
-
|
|
235
|
+
logging.info(f"Ao carregar tabela '{table_name}', nao foi possivel converter dados da coluna {col} para bool.")
|
|
231
236
|
raise ValueError(f"Erro ao converter coluna {col} para bool na tabela '{table_name}'.")
|
|
232
237
|
|
|
233
238
|
for col in table_columns.intersection(str_nan_format):
|
|
@@ -238,7 +243,7 @@ class LuxorQuery:
|
|
|
238
243
|
return table_data.copy(), table_path, update_time
|
|
239
244
|
|
|
240
245
|
except Exception:
|
|
241
|
-
|
|
246
|
+
logging.info(f"Nao foi possivel carregar a tabela <{table_name}>.")
|
|
242
247
|
return None, None, None
|
|
243
248
|
|
|
244
249
|
#def __load_csv(table_name):
|
|
@@ -249,7 +254,7 @@ class LuxorQuery:
|
|
|
249
254
|
# table_data = pd.read_csv(table_path, sep=";")
|
|
250
255
|
# return table_data.copy(), table_path, update_time
|
|
251
256
|
# except Exception:
|
|
252
|
-
#
|
|
257
|
+
# logging.info(f"Nao foi possivel carregar a tabela <{table_name}> no formato .csv")
|
|
253
258
|
# return None, None, None
|
|
254
259
|
#
|
|
255
260
|
#def __load_excel(table_name):
|
|
@@ -258,7 +263,7 @@ class LuxorQuery:
|
|
|
258
263
|
# update_time = os.path.getmtime(table_path)
|
|
259
264
|
# # Nao deixar crashar caso nao consiga ler do excel !
|
|
260
265
|
# table_data = pd.read_excel(table_path)
|
|
261
|
-
#
|
|
266
|
+
# logging.info(f"Tabela {table_name} carregada do arquivo em excel. Limite 1M de linhas.")
|
|
262
267
|
# return table_data.copy(), table_path, update_time
|
|
263
268
|
# except FileNotFoundError:
|
|
264
269
|
# return None, table_path, None
|
|
@@ -271,7 +276,7 @@ class LuxorQuery:
|
|
|
271
276
|
|
|
272
277
|
#assert(table_data is not None)
|
|
273
278
|
if table_data is None:
|
|
274
|
-
|
|
279
|
+
logging.info(f"Nao foi possivel carregar a tabela <{table_name}>.")
|
|
275
280
|
return table_data
|
|
276
281
|
|
|
277
282
|
if index:
|
|
@@ -279,7 +284,7 @@ class LuxorQuery:
|
|
|
279
284
|
table_data = table_data.set_index(index_name, drop=True)
|
|
280
285
|
|
|
281
286
|
except Exception:
|
|
282
|
-
|
|
287
|
+
logging.info(f"Nao foi possível setar a coluna {index_name} como index para a tabela {table_name}.")
|
|
283
288
|
|
|
284
289
|
#table_data = self.__persist_column_formatting(table_data)
|
|
285
290
|
|
|
@@ -362,17 +367,17 @@ class LuxorQuery:
|
|
|
362
367
|
|
|
363
368
|
except PermissionError:
|
|
364
369
|
hist_prices_tables = [] # desconsidera appends feitos no loop nao concluido
|
|
365
|
-
|
|
366
|
-
|
|
370
|
+
logging.info("Não foi possível carregar as tabelas pois tem algum arquivo aberto.")
|
|
371
|
+
logging.info(f"Tentativas de atualização: {update_attempts} de {update_attempts_limit}")
|
|
367
372
|
time.sleep(30)
|
|
368
373
|
|
|
369
374
|
except:
|
|
370
|
-
|
|
371
|
-
|
|
375
|
+
logging.info("Não foi possivel carregar as tabelas.")
|
|
376
|
+
logging.info(f"Tentativas de atualização: {update_attempts} de {update_attempts_limit}")
|
|
372
377
|
time.sleep(5*update_attempts)
|
|
373
378
|
|
|
374
379
|
if not update_success:
|
|
375
|
-
|
|
380
|
+
logging.info("Nao foi possivel atualizar os dados. Execução finalizada.")
|
|
376
381
|
|
|
377
382
|
|
|
378
383
|
def text_to_lowercase(self, t):
|
|
@@ -386,7 +391,7 @@ class LuxorQuery:
|
|
|
386
391
|
try:
|
|
387
392
|
return t.map(lambda x: x.lower().strip() if isinstance(x, str) else x)
|
|
388
393
|
except AttributeError:
|
|
389
|
-
|
|
394
|
+
logging.info("Pendente de atualizacao para o python 3.12.2")
|
|
390
395
|
return t.applymap(lambda x: x.lower().strip() if isinstance(x, str) else x)
|
|
391
396
|
|
|
392
397
|
def get_px_update_time(self):
|
|
@@ -441,7 +446,7 @@ class LuxorQuery:
|
|
|
441
446
|
usdbrl = self.get_price(usdbrl_ticker, px_date=px_date)
|
|
442
447
|
currency_factor = usdbrl
|
|
443
448
|
except ValueError:
|
|
444
|
-
|
|
449
|
+
logging.info(f"Erro ao converter moeda para {currency} para o ticker '{ticker}'.")
|
|
445
450
|
currency_factor = 1
|
|
446
451
|
|
|
447
452
|
ticker = ticker.lower()
|
|
@@ -475,11 +480,11 @@ class LuxorQuery:
|
|
|
475
480
|
else:
|
|
476
481
|
#if px_last_at_date is None:
|
|
477
482
|
if logger_level == "trace":
|
|
478
|
-
|
|
483
|
+
logging.info(f"Preço nao disponivel para o ticker '{ticker}'. Preço setado para 0.")
|
|
479
484
|
elif logger_level == "info":
|
|
480
|
-
|
|
485
|
+
logging.info(f"Preço nao disponivel para o ticker '{ticker}'. Preço setado para 0.")
|
|
481
486
|
else: # logger_level == "erro":
|
|
482
|
-
|
|
487
|
+
logging.info(f"Preço nao disponivel para o ticker '{ticker}'. Preço setado para 0.")
|
|
483
488
|
px_last_at_date = 0
|
|
484
489
|
|
|
485
490
|
|
|
@@ -509,13 +514,13 @@ class LuxorQuery:
|
|
|
509
514
|
except (IndexError , KeyError):
|
|
510
515
|
# Nao achou o ativo em nenhuma das tabelas, retorna 0
|
|
511
516
|
if logger_level == "trace":
|
|
512
|
-
|
|
517
|
+
logging.info(f"Preço nao disponivel para o tikcker '{ticker}'. Preço setado para 0.")
|
|
513
518
|
elif logger_level == "info":
|
|
514
|
-
|
|
519
|
+
logging.info(f"Preço nao disponivel para o tikcker '{ticker}'. Preço setado para 0.")
|
|
515
520
|
else: # logger_level == "erro":
|
|
516
|
-
|
|
521
|
+
logging.info(f"Preço nao disponivel para o tikcker '{ticker}'. Preço setado para 0.")
|
|
517
522
|
|
|
518
|
-
|
|
523
|
+
logging.info(f"Preço nao disponivel para o tikcker '{ticker}'. Preço setado para 0.")
|
|
519
524
|
self.price_cache[cache_key] = px_last_at_date
|
|
520
525
|
return 0
|
|
521
526
|
|
|
@@ -640,7 +645,7 @@ class LuxorQuery:
|
|
|
640
645
|
force_month_end=force_month_end)
|
|
641
646
|
|
|
642
647
|
if recent_date < previous_date:
|
|
643
|
-
|
|
648
|
+
logging.info("Possivel inversao dos parametros de inicio e fim do periodo.")
|
|
644
649
|
temp = recent_date
|
|
645
650
|
recent_date = previous_date
|
|
646
651
|
previous_date = temp
|
|
@@ -707,7 +712,7 @@ class LuxorQuery:
|
|
|
707
712
|
|
|
708
713
|
if p[0] == 'not found':
|
|
709
714
|
assets_not_found = list(p[1]["Asset"].unique())
|
|
710
|
-
|
|
715
|
+
logging.info(f"currency_map nao suporta Location dos ativos {assets_not_found}.")
|
|
711
716
|
continue
|
|
712
717
|
price_currency = p[0]
|
|
713
718
|
|
|
@@ -769,7 +774,7 @@ class LuxorQuery:
|
|
|
769
774
|
|
|
770
775
|
convertion_data = convertion_rule.get(price_currency+"_"+dest_currency, None)
|
|
771
776
|
if convertion_data is None:
|
|
772
|
-
|
|
777
|
+
logging.info(f"Conversao de moeda nao disponivel para {price_currency} -> {dest_currency}.")
|
|
773
778
|
prices = pd.DataFrame({}, columns=prices.columns)
|
|
774
779
|
return prices
|
|
775
780
|
convertion_ticker = convertion_data["currency_ticker"]
|
|
@@ -810,19 +815,19 @@ class LuxorQuery:
|
|
|
810
815
|
data_value = self.last_all_flds[ticker+"_"+flds]["Value"]
|
|
811
816
|
except KeyError:
|
|
812
817
|
if logger_level == "trace":
|
|
813
|
-
|
|
818
|
+
logging.info(f"Dado de {flds} nao disponivel para o ticker '{ticker}'.")
|
|
814
819
|
elif logger_level == "info":
|
|
815
|
-
|
|
820
|
+
logging.info(f"Dado de {flds} nao disponivel para o ticker '{ticker}'.")
|
|
816
821
|
else: # logger_level == "erro":
|
|
817
|
-
|
|
822
|
+
logging.info(f"Dado de {flds} nao disponivel para o ticker '{ticker}'.")
|
|
818
823
|
return None
|
|
819
824
|
except KeyError:
|
|
820
825
|
if logger_level == "trace":
|
|
821
|
-
|
|
826
|
+
logging.info(f"Dado de {flds} nao disponivel para o ticker '{ticker}'.")
|
|
822
827
|
elif logger_level == "info":
|
|
823
|
-
|
|
828
|
+
logging.info(f"Dado de {flds} nao disponivel para o ticker '{ticker}'.")
|
|
824
829
|
else: # logger_level == "erro":
|
|
825
|
-
|
|
830
|
+
logging.info(f"Dado de {flds} nao disponivel para o ticker '{ticker}'.")
|
|
826
831
|
return None
|
|
827
832
|
|
|
828
833
|
# Formatando o valor retornado
|
|
@@ -833,7 +838,7 @@ class LuxorQuery:
|
|
|
833
838
|
if data_type == "date":
|
|
834
839
|
return dt.datetime.fromtimestamp(float(data_value))
|
|
835
840
|
if data_type != "text":
|
|
836
|
-
|
|
841
|
+
logging.info(f"field '{flds}' nao foi cadastrado na tabela field_map.")
|
|
837
842
|
return data_value
|
|
838
843
|
|
|
839
844
|
# Buscamos por dado numa data especifica.
|
|
@@ -845,7 +850,7 @@ class LuxorQuery:
|
|
|
845
850
|
if len(data) > 0:
|
|
846
851
|
return data.tail(1).squeeze()
|
|
847
852
|
except KeyError:
|
|
848
|
-
|
|
853
|
+
logging.info(f"Dado de {flds} nao disponivel para o ticker '{ticker}'.")
|
|
849
854
|
# Nenhum dado encontrado para a data informada
|
|
850
855
|
return None
|
|
851
856
|
|
|
@@ -1061,11 +1066,11 @@ class LuxorQuery:
|
|
|
1061
1066
|
complementary_previous_date=previous_date
|
|
1062
1067
|
|
|
1063
1068
|
if previous_date < dt.date(2018,12,31) and cash_ticker == 'jpmutcc lx equity':
|
|
1064
|
-
#
|
|
1069
|
+
#logging.info(f"Nao ha datas anteriores a {dt.date(2018,12,31)} para o JPMUTCC. Sera usada essa.")
|
|
1065
1070
|
previous_date = dt.date(2018,12,31)
|
|
1066
1071
|
|
|
1067
1072
|
if previous_date < dt.date(2020,3,2) and cash_ticker == 'sofrindx index':
|
|
1068
|
-
#
|
|
1073
|
+
#logging.info(f"Nao ha datas anteriores a {dt.date(2018,12,31)} para o JPMUTCC. Sera usada essa.")
|
|
1069
1074
|
previous_date = dt.date(2020,3,2)
|
|
1070
1075
|
|
|
1071
1076
|
|
|
@@ -1174,7 +1179,7 @@ class LuxorQuery:
|
|
|
1174
1179
|
force_month_end=force_month_end)
|
|
1175
1180
|
|
|
1176
1181
|
if recent_date < previous_date:
|
|
1177
|
-
|
|
1182
|
+
logging.info("Possivel inversao dos parametros de inicio e fim do periodo.")
|
|
1178
1183
|
temp = recent_date
|
|
1179
1184
|
recent_date = previous_date
|
|
1180
1185
|
previous_date = temp
|
|
@@ -1197,7 +1202,7 @@ class LuxorQuery:
|
|
|
1197
1202
|
if (previous_price == 0) or (previous_date is None) or (previous_price is None):
|
|
1198
1203
|
return 0
|
|
1199
1204
|
except ValueError:
|
|
1200
|
-
|
|
1205
|
+
logging.info(f"ValueError:\nticker:{ticker} previous_price: {previous_price} previous_date:{previous_date}")
|
|
1201
1206
|
|
|
1202
1207
|
if adjust_amortization:
|
|
1203
1208
|
last_price = self.get_quota_adjusted_by_amortization(ticker, last_price, recent_date)
|
|
@@ -1211,7 +1216,7 @@ class LuxorQuery:
|
|
|
1211
1216
|
usdbrl_ticker="bmfxclco curncy", adjust_amortization=False, force_month_end=False):
|
|
1212
1217
|
#TODO -> garantir que a tabela de precos esta sendo atualizada pelos precos no intraday
|
|
1213
1218
|
if adjust_amortization:
|
|
1214
|
-
|
|
1219
|
+
logging.info("Ajuste de amortizacao ainda NAO implementado para esse metodo.")
|
|
1215
1220
|
# Aproveitando a get_prices, para realizar as filtragens
|
|
1216
1221
|
pct_changes = self.get_prices(tickers=tickers, recent_date=recent_date,
|
|
1217
1222
|
previous_date=previous_date, currency=currency,
|
|
@@ -2344,7 +2349,7 @@ class LuxorQuery:
|
|
|
2344
2349
|
|
|
2345
2350
|
return float(hist_metrics[metrics].squeeze())
|
|
2346
2351
|
except KeyError:
|
|
2347
|
-
|
|
2352
|
+
logging.info(f"Metrica(s) {metrics} indisponivel(is)")
|
|
2348
2353
|
|
|
2349
2354
|
|
|
2350
2355
|
def get_risk_metric_variation(self, fund_name, recent_date, previous_date, metrics=None):
|
|
@@ -2370,7 +2375,7 @@ class LuxorQuery:
|
|
|
2370
2375
|
"""
|
|
2371
2376
|
|
|
2372
2377
|
if (previous_date is not None) and (previous_date > recent_date):
|
|
2373
|
-
|
|
2378
|
+
logging.info("Data inicial é menor que a data final. Parametros invertidos?")
|
|
2374
2379
|
sys.exit()
|
|
2375
2380
|
|
|
2376
2381
|
# Obtendo tabela de retornos historicos extraida do retorno consolidado
|
|
@@ -2395,7 +2400,7 @@ class LuxorQuery:
|
|
|
2395
2400
|
if type(segments) is list:
|
|
2396
2401
|
seg_filter = segments
|
|
2397
2402
|
else:
|
|
2398
|
-
|
|
2403
|
+
logging.info("'segments' precisa ser do tipo 'list' ou 'str'")
|
|
2399
2404
|
sys.exit()
|
|
2400
2405
|
|
|
2401
2406
|
group_results = group_results.query(" Segment.isin(@seg_filter)").copy()
|
|
@@ -2617,7 +2622,7 @@ class LuxorQuery:
|
|
|
2617
2622
|
return next_date
|
|
2618
2623
|
return month_ending
|
|
2619
2624
|
return next_date
|
|
2620
|
-
|
|
2625
|
+
logging.info("'mode' desconhecido.")
|
|
2621
2626
|
|
|
2622
2627
|
|
|
2623
2628
|
def calculate_attribution(self, fund, previous_date, recent_date, fund_currency):
|
|
@@ -140,22 +140,44 @@ class TableDataLoader:
|
|
|
140
140
|
self.tracked_files[directory] = blob_watcher
|
|
141
141
|
|
|
142
142
|
|
|
143
|
-
def table_load_triggered(self) -> bool:
|
|
144
|
-
"""Verifica se alguma das trigger tables foi atualizada.
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
143
|
+
def table_load_triggered(self, trigger_mode="any") -> bool:
|
|
144
|
+
"""Verifica se alguma das trigger tables foi atualizada.
|
|
145
|
+
trigger_mode: "any" ou "all".
|
|
146
|
+
"""
|
|
147
|
+
|
|
148
|
+
if trigger_mode == "any":
|
|
149
|
+
load_triggered = False
|
|
150
|
+
# Verificando se alguma das tabelas foi atualizada
|
|
151
|
+
for trigger_path in self.tracked_files.keys():
|
|
152
|
+
blob_watcher = self.tracked_files[trigger_path]
|
|
153
|
+
file_updated, _, _ = blob_watcher.has_changed(blob_path = trigger_path,
|
|
154
|
+
update_snapshot=True,
|
|
155
|
+
treat_missing_as_changed=True
|
|
156
|
+
)
|
|
157
|
+
if file_updated:
|
|
158
|
+
load_triggered = True #load_triggered | True
|
|
159
|
+
|
|
160
|
+
return load_triggered
|
|
161
|
+
|
|
162
|
+
if trigger_mode == "all":
|
|
163
|
+
load_triggered = True
|
|
164
|
+
# Verificando se alguma das tabelas foi atualizada
|
|
165
|
+
for trigger_path in self.tracked_files.keys():
|
|
166
|
+
blob_watcher = self.tracked_files[trigger_path]
|
|
167
|
+
file_updated, _, _ = blob_watcher.has_changed(blob_path = trigger_path,
|
|
168
|
+
update_snapshot=False,
|
|
169
|
+
treat_missing_as_changed=True
|
|
170
|
+
)
|
|
171
|
+
if not file_updated:
|
|
172
|
+
load_triggered = False #load_triggered | True
|
|
173
|
+
if load_triggered:
|
|
174
|
+
# Fazer do estado dos snapshots
|
|
175
|
+
for trigger_path in self.tracked_files.keys():
|
|
176
|
+
blob_watcher = self.tracked_files[trigger_path]
|
|
177
|
+
blob_watcher.update_snapshot(trigger_path)
|
|
178
|
+
return load_triggered
|
|
179
|
+
|
|
180
|
+
|
|
159
181
|
|
|
160
182
|
def load_table(self):
|
|
161
183
|
"""Carrega a tabela via funcao de atualização.
|
|
@@ -294,55 +294,4 @@ class BlobChangeWatcher:
|
|
|
294
294
|
return changed_paths
|
|
295
295
|
|
|
296
296
|
|
|
297
|
-
class TableDataLoader:
|
|
298
297
|
|
|
299
|
-
def __init__(self, update_func: callable, kwargs: dict = {}, adls_connection_string: str = None ):
|
|
300
|
-
"""
|
|
301
|
-
Controla o carregamento de tabelas baseado em mudanças de arquivos no ADLS.
|
|
302
|
-
Args:
|
|
303
|
-
update_func (callable): Funcao que sera chamada para atualizar a tabela.
|
|
304
|
-
kwargs (dict): Dicionario com os argumentos para a funcao de update.
|
|
305
|
-
luxordb_path (Path, optional): Caminho para o diretorio raiz do luxorDB.
|
|
306
|
-
Defaults to None.
|
|
307
|
-
"""
|
|
308
|
-
self.tracked_files = {}
|
|
309
|
-
self.adls_connection_string = adls_connection_string
|
|
310
|
-
self.update_func = update_func
|
|
311
|
-
self.kwargs = kwargs
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
def add_load_trigger(self, directory: str, trigger_name: str):
|
|
315
|
-
""" Adiciona tabela na lista para controle de alteracao.
|
|
316
|
-
O load sera disparado quando essa tabela for atualizada.
|
|
317
|
-
Args:
|
|
318
|
-
table_path (Path): Path para a tabela que ira disparar a atualizacao.
|
|
319
|
-
"""
|
|
320
|
-
|
|
321
|
-
blob_watcher = BlobChangeWatcher(watcher_id=trigger_name,
|
|
322
|
-
adls_connection_string=self.adls_connection_string)
|
|
323
|
-
self.tracked_files[directory] = blob_watcher
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
def table_load_triggered(self) -> bool:
|
|
327
|
-
"""Verifica se alguma das trigger tables foi atualizada."""
|
|
328
|
-
|
|
329
|
-
load_triggered = False
|
|
330
|
-
# Verificando se alguma das tabelas foi atualizada
|
|
331
|
-
for trigger_path in self.tracked_files.keys():
|
|
332
|
-
blob_watcher = self.tracked_files[trigger_path]
|
|
333
|
-
file_updated, _, _ = blob_watcher.has_changed(blob_path = trigger_path,
|
|
334
|
-
update_snapshot=True,
|
|
335
|
-
treat_missing_as_changed=True
|
|
336
|
-
)
|
|
337
|
-
if file_updated:
|
|
338
|
-
load_triggered = True #load_triggered | True
|
|
339
|
-
|
|
340
|
-
return load_triggered
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
def load_table(self):
|
|
344
|
-
"""Carrega a tabela no luxorDB.
|
|
345
|
-
Args:
|
|
346
|
-
kwargs (dict): Dicionario com os argumentos para a funcao de update.
|
|
347
|
-
"""
|
|
348
|
-
self.update_func(**self.kwargs)
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
luxorasap/__init__.py,sha256=
|
|
1
|
+
luxorasap/__init__.py,sha256=PROECEFenSv7riGfWipnJstnJs8Qykozh2Wq0ZMlAwg,1356
|
|
2
2
|
luxorasap/btgapi/__init__.py,sha256=QUlfb5oiBY6K1Q5x4-a-x2wECe1At5wc2962I5odOJk,620
|
|
3
3
|
luxorasap/btgapi/auth.py,sha256=PvyCtbEyBO2B1CIeAlNXWugKW1OgiKfPcVzS6K5FBnQ,1872
|
|
4
4
|
luxorasap/btgapi/reports.py,sha256=ZVEMLoJPXc0r3XjPJPMsKQN0zZd1Npd7umNpAj1bncs,8040
|
|
5
5
|
luxorasap/btgapi/trades.py,sha256=956HZ9BvN9C_VQvKTyBLN0x6ZygwVqBZN11F7OnNbDI,5985
|
|
6
6
|
luxorasap/datareader/__init__.py,sha256=41RAvbrQ4R6oj67S32CrKqolx0CJ2W8cbOF6g5Cqm2g,120
|
|
7
|
-
luxorasap/datareader/core.py,sha256=
|
|
7
|
+
luxorasap/datareader/core.py,sha256=4b4moVqXnmQ_MtSjVeQyXy5R5Vt_QJZSNUaveqO0Ge8,158055
|
|
8
8
|
luxorasap/ingest/__init__.py,sha256=gHkw8FU8TuRL5tfHkACxwsLHwLYX8SgX9xHkB8uTjww,831
|
|
9
|
-
luxorasap/ingest/cloud/__init__.py,sha256=
|
|
9
|
+
luxorasap/ingest/cloud/__init__.py,sha256=I0JZh9FbGnIVxu7VmiTXe8rKN_w5OWLULvkVkVZNeUk,7242
|
|
10
10
|
luxorasap/ingest/legacy_local/dataloader.py,sha256=DF3CvojDAi0itVDZPsQbmpl5pqMTNwOOpxTz4Ju8mho,12419
|
|
11
11
|
luxorasap/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
12
|
luxorasap/utils/dataframe/__init__.py,sha256=heKpmq58FmX35syzzwrHqlOWKYBkH2Z1jyqaQ_Vg-00,265
|
|
@@ -14,11 +14,11 @@ luxorasap/utils/dataframe/reader.py,sha256=Vzjdw-AeS1lnWEHQ8RZNh0kK93NWTp0NWVi_B
|
|
|
14
14
|
luxorasap/utils/dataframe/transforms.py,sha256=OIvlTTcjFX6bUhuQp_syEp7ssm4sLzwvgsag6n2Wl3k,2438
|
|
15
15
|
luxorasap/utils/storage/__init__.py,sha256=461GYJcPMXGjHuJ9y9D3BHOC_oUS9Re32nVu1AwKyIA,334
|
|
16
16
|
luxorasap/utils/storage/blob.py,sha256=vgCKMOiVgP-V1A2xZRhG3kJhPFU-LA9E9kddOQTxYD8,9443
|
|
17
|
-
luxorasap/utils/storage/change_tracker.py,sha256=
|
|
17
|
+
luxorasap/utils/storage/change_tracker.py,sha256=HkeKc62UyD2BtP2gqafnJHZSBvYreH_7SQI1CYhn3Us,11709
|
|
18
18
|
luxorasap/utils/tools/__init__.py,sha256=dvK7Z4xnNQAuEiObVN7qjeLWAvP49JeFn2Oq9GdgmXs,76
|
|
19
19
|
luxorasap/utils/tools/excel.py,sha256=SfeTcbJWsWq3uKruwKSjJ4aWgMovITzlNXjP2bhdMjI,1246
|
|
20
|
-
luxorasap-0.2.
|
|
21
|
-
luxorasap-0.2.
|
|
22
|
-
luxorasap-0.2.
|
|
23
|
-
luxorasap-0.2.
|
|
24
|
-
luxorasap-0.2.
|
|
20
|
+
luxorasap-0.2.10.dist-info/METADATA,sha256=IOEkl3f4lMtJ2xJ0ln08fY6yJqrInkdW7FCBe3Aodl0,3804
|
|
21
|
+
luxorasap-0.2.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
22
|
+
luxorasap-0.2.10.dist-info/entry_points.txt,sha256=XFh-dOwUhlya9DmGvgookMI0ezyUJjcOvTIHDEYS44g,52
|
|
23
|
+
luxorasap-0.2.10.dist-info/top_level.txt,sha256=9YOL6bUIpzY06XFBRkUW1e4rgB32Ds91fQPGwUEjxzU,10
|
|
24
|
+
luxorasap-0.2.10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|