ingestr 0.13.51__py3-none-any.whl → 0.13.53__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 ingestr might be problematic. Click here for more details.

ingestr/main.py CHANGED
@@ -58,6 +58,7 @@ class LoaderFileFormat(str, Enum):
58
58
 
59
59
 
60
60
  class SqlBackend(str, Enum):
61
+ default = "default"
61
62
  sqlalchemy = "sqlalchemy"
62
63
  pyarrow = "pyarrow"
63
64
  connectorx = "connectorx"
@@ -187,7 +188,7 @@ def ingest(
187
188
  help="The SQL backend to use",
188
189
  envvar=["SQL_BACKEND", "INGESTR_SQL_BACKEND"],
189
190
  ),
190
- ] = SqlBackend.pyarrow, # type: ignore
191
+ ] = SqlBackend.default, # type: ignore
191
192
  loader_file_format: Annotated[
192
193
  Optional[LoaderFileFormat],
193
194
  typer.Option(
@@ -289,7 +290,11 @@ def ingest(
289
290
  from ingestr.src.collector.spinner import SpinnerCollector
290
291
  from ingestr.src.destinations import AthenaDestination
291
292
  from ingestr.src.factory import SourceDestinationFactory
292
- from ingestr.src.filters import cast_set_to_list, handle_mysql_empty_dates
293
+ from ingestr.src.filters import (
294
+ cast_set_to_list,
295
+ cast_spanner_types,
296
+ handle_mysql_empty_dates,
297
+ )
293
298
  from ingestr.src.sources import MongoDbSource
294
299
 
295
300
  def report_errors(run_info: LoadInfo):
@@ -517,6 +522,15 @@ def ingest(
517
522
  if interval_end:
518
523
  interval_end = interval_end.date() # type: ignore
519
524
 
525
+ if factory.source_scheme.startswith("spanner"):
526
+ # we tend to use the 'pyarrow' backend in general, however, it has issues with JSON objects, so we override it to 'sqlalchemy' for Spanner.
527
+ if sql_backend.value == SqlBackend.default:
528
+ sql_backend = SqlBackend.sqlalchemy
529
+
530
+ # this allows us to identify the cases where the user does not have a preference, so that for some sources we can override it.
531
+ if sql_backend == SqlBackend.default:
532
+ sql_backend = SqlBackend.pyarrow
533
+
520
534
  dlt_source = source.dlt_source(
521
535
  uri=source_uri,
522
536
  table=source_table,
@@ -535,6 +549,9 @@ def ingest(
535
549
  if factory.source_scheme.startswith("mysql"):
536
550
  resource.for_each(dlt_source, lambda x: x.add_map(handle_mysql_empty_dates))
537
551
 
552
+ if factory.source_scheme.startswith("spanner"):
553
+ resource.for_each(dlt_source, lambda x: x.add_map(cast_spanner_types))
554
+
538
555
  if yield_limit:
539
556
  resource.for_each(dlt_source, lambda x: x.add_limit(yield_limit))
540
557
 
ingestr/src/buildinfo.py CHANGED
@@ -1 +1 @@
1
- version = "v0.13.51"
1
+ version = "v0.13.53"
@@ -468,3 +468,33 @@ class S3Destination:
468
468
 
469
469
  def post_load(self) -> None:
470
470
  pass
471
+
472
+
473
+ class SqliteDestination(GenericSqlDestination):
474
+ def dlt_dest(self, uri: str, **kwargs):
475
+ return dlt.destinations.sqlalchemy(credentials=uri)
476
+
477
+ def dlt_run_params(self, uri: str, table: str, **kwargs):
478
+ return {
479
+ #https://dlthub.com/docs/dlt-ecosystem/destinations/sqlalchemy#dataset-files
480
+ "dataset_name": "main",
481
+ "table_name": table,
482
+ }
483
+
484
+
485
+ class MySqlDestination(GenericSqlDestination):
486
+ def dlt_dest(self, uri: str, **kwargs):
487
+ return dlt.destinations.sqlalchemy(credentials=uri)
488
+
489
+ def dlt_run_params(self, uri: str, table: str, **kwargs):
490
+ parsed = urlparse(uri)
491
+ database = parsed.path.lstrip("/")
492
+ if not database:
493
+ raise ValueError("You need to specify a database")
494
+ return {
495
+ "dataset_name": database,
496
+ "table_name": table,
497
+ }
498
+
499
+
500
+
ingestr/src/factory.py CHANGED
@@ -11,10 +11,12 @@ from ingestr.src.destinations import (
11
11
  DatabricksDestination,
12
12
  DuckDBDestination,
13
13
  MsSQLDestination,
14
+ MySqlDestination,
14
15
  PostgresDestination,
15
16
  RedshiftDestination,
16
17
  S3Destination,
17
18
  SnowflakeDestination,
19
+ SqliteDestination,
18
20
  SynapseDestination,
19
21
  )
20
22
  from ingestr.src.sources import (
@@ -52,18 +54,20 @@ from ingestr.src.sources import (
52
54
  PipedriveSource,
53
55
  S3Source,
54
56
  SalesforceSource,
57
+ SFTPSource,
55
58
  ShopifySource,
56
59
  SlackSource,
60
+ SmartsheetSource,
57
61
  SolidgateSource,
58
62
  SqlSource,
59
63
  StripeAnalyticsSource,
60
64
  TikTokSource,
61
65
  ZendeskSource,
62
- SmartsheetSource,
63
66
  )
64
67
 
65
68
  SQL_SOURCE_SCHEMES = [
66
69
  "bigquery",
70
+ "crate",
67
71
  "duckdb",
68
72
  "mssql",
69
73
  "mysql",
@@ -163,6 +167,7 @@ class SourceDestinationFactory:
163
167
  "attio": AttioSource,
164
168
  "solidgate": SolidgateSource,
165
169
  "smartsheet": SmartsheetSource,
170
+ "sftp": SFTPSource,
166
171
  }
167
172
  destinations: Dict[str, Type[DestinationProtocol]] = {
168
173
  "bigquery": BigQueryDestination,
@@ -182,6 +187,9 @@ class SourceDestinationFactory:
182
187
  "clickhouse+native": ClickhouseDestination,
183
188
  "clickhouse": ClickhouseDestination,
184
189
  "s3": S3Destination,
190
+ "sqlite": SqliteDestination,
191
+ "mysql": MySqlDestination,
192
+ "mysql+pymysql": MySqlDestination,
185
193
  }
186
194
 
187
195
  def __init__(self, source_uri: str, destination_uri: str):
ingestr/src/filters.py CHANGED
@@ -7,6 +7,20 @@ def cast_set_to_list(row):
7
7
  return row
8
8
 
9
9
 
10
+ def cast_spanner_types(row):
11
+ if not isinstance(row, dict):
12
+ return row
13
+
14
+ from google.cloud.spanner_v1.data_types import JsonObject
15
+
16
+ for key in row.keys():
17
+ if isinstance(row[key], JsonObject):
18
+ import json
19
+
20
+ row[key] = json.loads(row[key].serialize())
21
+ return row
22
+
23
+
10
24
  def handle_mysql_empty_dates(row):
11
25
  # MySQL returns empty dates as 0000-00-00, which is not a valid date, we handle them here.
12
26
  if not isinstance(row, dict):
@@ -43,7 +43,7 @@ def solidgate_source(
43
43
  yield solidgate_client.fetch_data(path, date_from=start_dt, date_to=end_dt)
44
44
 
45
45
  @dlt.resource(
46
- name="apm-orders",
46
+ name="apm_orders",
47
47
  write_disposition="merge",
48
48
  primary_key="order_id",
49
49
  columns={
@@ -69,7 +69,7 @@ def solidgate_source(
69
69
  yield solidgate_client.fetch_data(path, date_from=start_dt, date_to=end_dt)
70
70
 
71
71
  @dlt.resource(
72
- name="card-orders",
72
+ name="card_orders",
73
73
  write_disposition="merge",
74
74
  primary_key="order_id",
75
75
  columns={
@@ -95,7 +95,7 @@ def solidgate_source(
95
95
  yield solidgate_client.fetch_data(path, date_from=start_dt, date_to=end_dt)
96
96
 
97
97
  @dlt.resource(
98
- name="financial-entries",
98
+ name="financial_entries",
99
99
  write_disposition="merge",
100
100
  primary_key="id",
101
101
  columns={
ingestr/src/sources.py CHANGED
@@ -18,6 +18,7 @@ from typing import (
18
18
  )
19
19
  from urllib.parse import ParseResult, parse_qs, quote, urlencode, urlparse
20
20
 
21
+ import fsspec # type: ignore
21
22
  import pendulum
22
23
  from dlt.common.time import ensure_pendulum_datetime
23
24
  from dlt.extract import Incremental
@@ -78,31 +79,7 @@ class SqlSource:
78
79
  # clickhouse://<username>:<password>@<host>:<port>?secure=<secure>
79
80
  if uri.startswith("clickhouse://"):
80
81
  parsed_uri = urlparse(uri)
81
-
82
- username = parsed_uri.username
83
- if not username:
84
- raise ValueError(
85
- "A username is required to connect to the ClickHouse database."
86
- )
87
-
88
- password = parsed_uri.password
89
- if not password:
90
- raise ValueError(
91
- "A password is required to authenticate with the ClickHouse database."
92
- )
93
-
94
- host = parsed_uri.hostname
95
- if not host:
96
- raise ValueError(
97
- "The hostname or IP address of the ClickHouse server is required to establish a connection."
98
- )
99
-
100
- port = parsed_uri.port
101
- if not port:
102
- raise ValueError(
103
- "The TCP port of the ClickHouse server is required to establish a connection."
104
- )
105
-
82
+
106
83
  query_params = parse_qs(parsed_uri.query)
107
84
 
108
85
  if "http_port" in query_params:
@@ -2506,3 +2483,56 @@ class SolidgateSource:
2506
2483
  ).with_resources(table_name)
2507
2484
  except ResourcesNotFoundError:
2508
2485
  raise UnsupportedResourceError(table_name, "Solidgate")
2486
+
2487
+
2488
+ class SFTPSource:
2489
+ def handles_incrementality(self) -> bool:
2490
+ return True
2491
+
2492
+ def dlt_source(self, uri: str, table: str, **kwargs):
2493
+ parsed_uri = urlparse(uri)
2494
+ host = parsed_uri.hostname
2495
+ if not host:
2496
+ raise MissingValueError("host", "SFTP URI")
2497
+ port = parsed_uri.port or 22
2498
+ username = parsed_uri.username
2499
+ password = parsed_uri.password
2500
+
2501
+ params: Dict[str, Any] = {
2502
+ "host": host,
2503
+ "port": port,
2504
+ "username": username,
2505
+ "password": password,
2506
+ "look_for_keys": False,
2507
+ "allow_agent": False,
2508
+ }
2509
+
2510
+ try:
2511
+ fs = fsspec.filesystem("sftp", **params)
2512
+ except Exception as e:
2513
+ raise ConnectionError(
2514
+ f"Failed to connect or authenticate to sftp server {host}:{port}. Error: {e}"
2515
+ )
2516
+ bucket_url = f"sftp://{host}:{port}"
2517
+
2518
+ if table.startswith("/"):
2519
+ file_glob = table
2520
+ else:
2521
+ file_glob = f"/{table}"
2522
+
2523
+ file_extension = table.split(".")[-1].lower()
2524
+ endpoint: str
2525
+ if file_extension == "csv":
2526
+ endpoint = "read_csv"
2527
+ elif file_extension == "jsonl":
2528
+ endpoint = "read_jsonl"
2529
+ elif file_extension == "parquet":
2530
+ endpoint = "read_parquet"
2531
+ else:
2532
+ raise ValueError(
2533
+ "FTPServer Source only supports specific file formats: csv, jsonl, parquet."
2534
+ )
2535
+ from ingestr.src.filesystem import readers
2536
+
2537
+ dlt_source_resource = readers(bucket_url, fs, file_glob)
2538
+ return dlt_source_resource.with_resources(endpoint)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ingestr
3
- Version: 0.13.51
3
+ Version: 0.13.53
4
4
  Summary: ingestr is a command-line application that ingests data from various sources and stores them in any database.
5
5
  Project-URL: Homepage, https://github.com/bruin-data/ingestr
6
6
  Project-URL: Issues, https://github.com/bruin-data/ingestr/issues
@@ -26,6 +26,7 @@ Requires-Dist: asn1crypto==1.5.1
26
26
  Requires-Dist: asynch==0.2.4
27
27
  Requires-Dist: attrs==25.1.0
28
28
  Requires-Dist: backoff==2.2.1
29
+ Requires-Dist: bcrypt==4.3.0
29
30
  Requires-Dist: beautifulsoup4==4.13.3
30
31
  Requires-Dist: boto3==1.37.1
31
32
  Requires-Dist: botocore==1.37.1
@@ -39,6 +40,7 @@ Requires-Dist: clickhouse-connect==0.8.14
39
40
  Requires-Dist: clickhouse-driver==0.2.9
40
41
  Requires-Dist: clickhouse-sqlalchemy==0.2.7
41
42
  Requires-Dist: confluent-kafka==2.8.0
43
+ Requires-Dist: crate==2.0.0
42
44
  Requires-Dist: cryptography==44.0.2
43
45
  Requires-Dist: curlify==2.2.1
44
46
  Requires-Dist: databricks-sql-connector==2.9.3
@@ -59,6 +61,7 @@ Requires-Dist: flatten-json==0.1.14
59
61
  Requires-Dist: frozenlist==1.5.0
60
62
  Requires-Dist: fsspec==2025.3.2
61
63
  Requires-Dist: gcsfs==2025.3.2
64
+ Requires-Dist: geojson==3.2.0
62
65
  Requires-Dist: gitdb==4.0.12
63
66
  Requires-Dist: gitpython==3.1.44
64
67
  Requires-Dist: giturlparse==0.12.0
@@ -77,7 +80,7 @@ Requires-Dist: google-cloud-storage==3.1.0
77
80
  Requires-Dist: google-crc32c==1.6.0
78
81
  Requires-Dist: google-resumable-media==2.7.2
79
82
  Requires-Dist: googleapis-common-protos==1.69.0
80
- Requires-Dist: greenlet==3.2.2
83
+ Requires-Dist: greenlet==3.2.3
81
84
  Requires-Dist: grpc-google-iam-v1==0.14.2
82
85
  Requires-Dist: grpc-interceptor==0.15.4
83
86
  Requires-Dist: grpcio-status==1.62.3
@@ -113,6 +116,7 @@ Requires-Dist: openpyxl==3.1.5
113
116
  Requires-Dist: orjson==3.10.15
114
117
  Requires-Dist: packaging==24.2
115
118
  Requires-Dist: pandas==2.2.3
119
+ Requires-Dist: paramiko==3.5.1
116
120
  Requires-Dist: pathvalidate==3.2.3
117
121
  Requires-Dist: pendulum==3.0.0
118
122
  Requires-Dist: platformdirs==4.3.6
@@ -137,6 +141,7 @@ Requires-Dist: pygments==2.19.1
137
141
  Requires-Dist: pyjwt==2.10.1
138
142
  Requires-Dist: pymongo==4.11.1
139
143
  Requires-Dist: pymysql==1.1.1
144
+ Requires-Dist: pynacl==1.5.0
140
145
  Requires-Dist: pyopenssl==25.0.0
141
146
  Requires-Dist: pyparsing==3.2.1
142
147
  Requires-Dist: pyrate-limiter==3.7.0
@@ -170,6 +175,7 @@ Requires-Dist: snowflake-sqlalchemy==1.6.1
170
175
  Requires-Dist: sortedcontainers==2.4.0
171
176
  Requires-Dist: soupsieve==2.6
172
177
  Requires-Dist: sqlalchemy-bigquery==1.12.1
178
+ Requires-Dist: sqlalchemy-cratedb==0.42.0.dev2
173
179
  Requires-Dist: sqlalchemy-hana==2.0.0
174
180
  Requires-Dist: sqlalchemy-redshift==0.8.14
175
181
  Requires-Dist: sqlalchemy-spanner==1.11.0
@@ -192,6 +198,7 @@ Requires-Dist: tzdata==2025.1
192
198
  Requires-Dist: tzlocal==5.3
193
199
  Requires-Dist: uritemplate==4.1.1
194
200
  Requires-Dist: urllib3==2.3.0
201
+ Requires-Dist: verlib2==0.3.1
195
202
  Requires-Dist: wrapt==1.17.2
196
203
  Requires-Dist: yarl==1.18.3
197
204
  Requires-Dist: zeep==4.3.1
@@ -292,11 +299,21 @@ Pull requests are welcome. However, please open an issue first to discuss what y
292
299
  <td>✅</td>
293
300
  <td>✅</td>
294
301
  </tr>
302
+ <tr>
303
+ <td>CrateDB</td>
304
+ <td>✅</td>
305
+ <td>❌</td>
306
+ </tr>
295
307
  <tr>
296
308
  <td>Databricks</td>
297
309
  <td>✅</td>
298
310
  <td>✅</td>
299
311
  </tr>
312
+ <tr>
313
+ <td>IBM Db2</td>
314
+ <td>✅</td>
315
+ <td>-</td>
316
+ </tr>
300
317
  <tr>
301
318
  <td>DuckDB</td>
302
319
  <td>✅</td>
@@ -307,6 +324,16 @@ Pull requests are welcome. However, please open an issue first to discuss what y
307
324
  <td>✅</td>
308
325
  <td>-</td>
309
326
  </tr>
327
+ <tr>
328
+ <td>Elasticsearch</td>
329
+ <td>✅</td>
330
+ <td>-</td>
331
+ </tr>
332
+ <tr>
333
+ <td>GCP Spanner</td>
334
+ <td>✅</td>
335
+ <td>-</td>
336
+ </tr>
310
337
  <tr>
311
338
  <td>Local CSV file</td>
312
339
  <td>✅</td>
@@ -393,6 +420,11 @@ Pull requests are welcome. However, please open an issue first to discuss what y
393
420
  <td>✅</td>
394
421
  <td>-</td>
395
422
  </tr>
423
+ <tr>
424
+ <td>Attio</td>
425
+ <td>✅</td>
426
+ <td>-</td>
427
+ </tr>
396
428
  <tr>
397
429
  <td>Chess.com</td>
398
430
  <td>✅</td>
@@ -404,7 +436,7 @@ Pull requests are welcome. However, please open an issue first to discuss what y
404
436
  <td>-</td>
405
437
  </tr>
406
438
  <tr>
407
- <td>Github</td>
439
+ <td>GitHub</td>
408
440
  <td>✅</td>
409
441
  <td>-</td>
410
442
  </tr>
@@ -447,6 +479,16 @@ Pull requests are welcome. However, please open an issue first to discuss what y
447
479
  <td>Personio</td>
448
480
  <td>✅</td>
449
481
  <td>-</td>
482
+ </tr>
483
+ <tr>
484
+ <td>Phantombuster</td>
485
+ <td>✅</td>
486
+ <td>-</td>
487
+ </tr>
488
+ <tr>
489
+ <td>Pipedrive</td>
490
+ <td>✅</td>
491
+ <td>-</td>
450
492
  </tr>
451
493
  <tr>
452
494
  <td>S3</td>
@@ -469,7 +511,12 @@ Pull requests are welcome. However, please open an issue first to discuss what y
469
511
  <td>-</td>
470
512
  </tr>
471
513
  <tr>
472
- <td>Smartsheet</td>
514
+ <td>Smartsheets</td>
515
+ <td>✅</td>
516
+ <td>-</td>
517
+ </tr>
518
+ <tr>
519
+ <td>Solidgate</td>
473
520
  <td>✅</td>
474
521
  <td>-</td>
475
522
  </tr>
@@ -1,17 +1,17 @@
1
1
  ingestr/conftest.py,sha256=Q03FIJIZpLBbpj55cfCHIKEjc1FCvWJhMF2cidUJKQU,1748
2
- ingestr/main.py,sha256=rHxHQAbd0ccW2e2kQSWlv7-5qcc2ZB6Eh3vyjm4Nzns,25550
2
+ ingestr/main.py,sha256=GkC1hdq8AVGrvolc95zMfjmibI95p2pmFkbgCOVf-Og,26311
3
3
  ingestr/src/.gitignore,sha256=8cX1AZTSI0TcdZFGTmS_oyBjpfCzhOEt0DdAo2dFIY8,203
4
4
  ingestr/src/blob.py,sha256=onMe5ZHxPXTdcB_s2oGNdMo-XQJ3ajwOsWE9eSTGFmc,1495
5
- ingestr/src/buildinfo.py,sha256=ZgugQZPIlr-_7kRH5qIupQ5e48JTOHSlRWEsmNx4wXw,21
6
- ingestr/src/destinations.py,sha256=41Bj1UgxR8a2KcZWqtGw74AKZKnSBrueQRnBdrf3c-A,16003
5
+ ingestr/src/buildinfo.py,sha256=TRZbcB7mFeJZcDA_BqTjZvRtxs0161pLvM9EmkNt90U,21
6
+ ingestr/src/destinations.py,sha256=wYE6p_DC9HrQ5KehhgbLxgnkS1P9wE9L21Hw_lgAZ70,16884
7
7
  ingestr/src/errors.py,sha256=Ufs4_DfE77_E3vnA1fOQdi6cmuLVNm7_SbFLkL1XPGk,686
8
- ingestr/src/factory.py,sha256=JeK0M8C05-_KxxIhtevs-MJGLlngXUQupd-Pm4Fg904,5803
9
- ingestr/src/filters.py,sha256=C-_TIVkF_cxZBgG-Run2Oyn0TAhJgA8IWXZ-OPY3uek,1136
8
+ ingestr/src/factory.py,sha256=wDa3F7xbnQcQwfnQIbxWypuJ1G8GGhRpdssWRPtEO_Q,6020
9
+ ingestr/src/filters.py,sha256=LLecXe9QkLFkFLUZ92OXNdcANr1a8edDxrflc2ko_KA,1452
10
10
  ingestr/src/http_client.py,sha256=bxqsk6nJNXCo-79gW04B53DQO-yr25vaSsqP0AKtjx4,732
11
11
  ingestr/src/loader.py,sha256=9NaWAyfkXdqAZSS-N72Iwo36Lbx4PyqIfaaH1dNdkFs,1712
12
12
  ingestr/src/partition.py,sha256=BrIP6wFJvyR7Nus_3ElnfxknUXeCipK_E_bB8kZowfc,969
13
13
  ingestr/src/resource.py,sha256=ZqmZxFQVGlF8rFPhBiUB08HES0yoTj8sZ--jKfaaVps,1164
14
- ingestr/src/sources.py,sha256=SnFxil6gU5RIYiSUfE6Upq2se0YeRSuTIKK3Jxn-YKI,86587
14
+ ingestr/src/sources.py,sha256=sEi-09LXySuhHqUpscHlfQTmQ_7Bgq1GDY_y5mma-sg,87437
15
15
  ingestr/src/table_definition.py,sha256=REbAbqdlmUMUuRh8nEQRreWjPVOQ5ZcfqGkScKdCrmk,390
16
16
  ingestr/src/time.py,sha256=H_Fk2J4ShXyUM-EMY7MqCLZQhlnZMZvO952bmZPc4yE,254
17
17
  ingestr/src/version.py,sha256=J_2xgZ0mKlvuHcjdKCx2nlioneLH0I47JiU_Slr_Nwc,189
@@ -109,7 +109,7 @@ ingestr/src/slack/__init__.py,sha256=pyDukxcilqTAe_bBzfWJ8Vxi83S-XEdEFBH2pEgILrM
109
109
  ingestr/src/slack/helpers.py,sha256=08TLK7vhFvH_uekdLVOLF3bTDe1zgH0QxHObXHzk1a8,6545
110
110
  ingestr/src/slack/settings.py,sha256=NhKn4y1zokEa5EmIZ05wtj_-I0GOASXZ5V81M1zXCtY,457
111
111
  ingestr/src/smartsheets/__init__.py,sha256=pdzSV7rA0XYD5Xa1u4zb6vziy5iFXIQNROkpJ9oYas0,1623
112
- ingestr/src/solidgate/__init__.py,sha256=DZYQ4M3Cc7AIbdQcNQm_6yX2whnFhE-iM10-ACJ3W3A,3626
112
+ ingestr/src/solidgate/__init__.py,sha256=JdaXvAu5QGuf9-FY294vwCQCEmfrqIld9oqbzqCJS3g,3626
113
113
  ingestr/src/solidgate/helpers.py,sha256=oePEc9nnvmN3IaKrfJCvyKL79xdGM0-gRTN3-8tY4Fc,4952
114
114
  ingestr/src/sql_database/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
115
115
  ingestr/src/sql_database/callbacks.py,sha256=sEFFmXxAURY3yeBjnawigDtq9LBCvi8HFqG4kLd7tMU,2002
@@ -135,8 +135,8 @@ ingestr/testdata/merge_expected.csv,sha256=DReHqWGnQMsf2PBv_Q2pfjsgvikYFnf1zYcQZ
135
135
  ingestr/testdata/merge_part1.csv,sha256=Pw8Z9IDKcNU0qQHx1z6BUf4rF_-SxKGFOvymCt4OY9I,185
136
136
  ingestr/testdata/merge_part2.csv,sha256=T_GiWxA81SN63_tMOIuemcvboEFeAmbKc7xRXvL9esw,287
137
137
  ingestr/tests/unit/test_smartsheets.py,sha256=eiC2CCO4iNJcuN36ONvqmEDryCA1bA1REpayHpu42lk,5058
138
- ingestr-0.13.51.dist-info/METADATA,sha256=danPRyBhqlvyOwtw8kBmBh5FEY_xH6upsy5GrsFaMg4,13983
139
- ingestr-0.13.51.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
140
- ingestr-0.13.51.dist-info/entry_points.txt,sha256=oPJy0KBnPWYjDtP1k8qwAihcTLHSZokSQvRAw_wtfJM,46
141
- ingestr-0.13.51.dist-info/licenses/LICENSE.md,sha256=cW8wIhn8HFE-KLStDF9jHQ1O_ARWP3kTpk_-eOccL24,1075
142
- ingestr-0.13.51.dist-info/RECORD,,
138
+ ingestr-0.13.53.dist-info/METADATA,sha256=vVMGPiZ4snksSxZGUKgNl0a3bfSxUBeTrWpUG0lHFhw,14902
139
+ ingestr-0.13.53.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
140
+ ingestr-0.13.53.dist-info/entry_points.txt,sha256=oPJy0KBnPWYjDtP1k8qwAihcTLHSZokSQvRAw_wtfJM,46
141
+ ingestr-0.13.53.dist-info/licenses/LICENSE.md,sha256=cW8wIhn8HFE-KLStDF9jHQ1O_ARWP3kTpk_-eOccL24,1075
142
+ ingestr-0.13.53.dist-info/RECORD,,