python-table-converter 0.2.9__tar.gz → 0.2.10__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 (16) hide show
  1. {python_table_converter-0.2.9 → python_table_converter-0.2.10}/PKG-INFO +1 -1
  2. {python_table_converter-0.2.9 → python_table_converter-0.2.10}/pyproject.toml +1 -1
  3. python_table_converter-0.2.10/table_converter/__init__.py +2 -0
  4. {python_table_converter-0.2.9 → python_table_converter-0.2.10}/table_converter/commands/convert_tables.py +12 -0
  5. {python_table_converter-0.2.9 → python_table_converter-0.2.10}/table_converter/core/config.py +14 -2
  6. {python_table_converter-0.2.9 → python_table_converter-0.2.10}/table_converter/core/convert.py +61 -7
  7. python_table_converter-0.2.9/table_converter/__init__.py +0 -2
  8. {python_table_converter-0.2.9 → python_table_converter-0.2.10}/LICENSE +0 -0
  9. {python_table_converter-0.2.9 → python_table_converter-0.2.10}/README.md +0 -0
  10. {python_table_converter-0.2.9 → python_table_converter-0.2.10}/table_converter/cli.py +0 -0
  11. {python_table_converter-0.2.9 → python_table_converter-0.2.10}/table_converter/core/constants.py +0 -0
  12. {python_table_converter-0.2.9 → python_table_converter-0.2.10}/table_converter/core/functions/assign_id.py +0 -0
  13. {python_table_converter-0.2.9 → python_table_converter-0.2.10}/table_converter/core/functions/flatten.py +0 -0
  14. {python_table_converter-0.2.9 → python_table_converter-0.2.10}/table_converter/core/functions/get_field_value.py +0 -0
  15. {python_table_converter-0.2.9 → python_table_converter-0.2.10}/table_converter/core/functions/search_column_value.py +0 -0
  16. {python_table_converter-0.2.9 → python_table_converter-0.2.10}/table_converter/core/functions/set_field_value.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-table-converter
3
- Version: 0.2.9
3
+ Version: 0.2.10
4
4
  Summary: A table data converter
5
5
  Home-page: https://github.com/akivajp/python-table-converter
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "python-table-converter"
3
- version = "0.2.9"
3
+ version = "0.2.10"
4
4
  description = "A table data converter"
5
5
  authors = ["Akiva Miura <akiva.miura@gmail.com>"]
6
6
  license = "MIT"
@@ -0,0 +1,2 @@
1
+ __version__ = "0.2.10"
2
+ __version_tuple__ = (0, 2, 10)
@@ -15,9 +15,11 @@ def run(
15
15
  config_path = args.config,
16
16
  assign_constants = args.assign_constants,
17
17
  assign_formats = args.assign_formats,
18
+ str_filters = args.filters,
18
19
  pickup_columns= args.pickup_columns,
19
20
  fields_to_split_by_newline = args.split_by_newline,
20
21
  fields_to_assign_ids = args.assign_ids,
22
+ str_omit_fields= args.omit_fields,
21
23
  output_debug = args.output_debug,
22
24
  )
23
25
 
@@ -66,6 +68,16 @@ def setup_parser(
66
68
  type=str,
67
69
  help='Field to assign formats',
68
70
  )
71
+ parser.add_argument(
72
+ '--filters', '--filter', '-f',
73
+ type=str,
74
+ help='Expression list to filter records',
75
+ )
76
+ parser.add_argument(
77
+ '--omit-fields', '--omit',
78
+ type=str,
79
+ help='Field to omit',
80
+ )
69
81
  parser.add_argument(
70
82
  '--output-debug',
71
83
  action='store_true',
@@ -2,7 +2,10 @@
2
2
 
3
3
  from collections import OrderedDict
4
4
  import dataclasses
5
- from typing import Mapping
5
+ from typing import (
6
+ Literal,
7
+ Mapping,
8
+ )
6
9
 
7
10
  from icecream import ic
8
11
  import yaml
@@ -18,12 +21,20 @@ class AssignIdConfig:
18
21
  primary: list[str]
19
22
  context: list[str] | None = None
20
23
 
24
+ @dataclasses.dataclass
25
+ class FilterConfig:
26
+ field: str
27
+ operator: Literal['==', '!=', '>', '>=', '<', '<=']
28
+ value: str
29
+
21
30
  @dataclasses.dataclass
22
31
  class ProcessConfig:
23
32
  assign_constants: FlatFieldMap = dataclasses.field(default_factory=OrderedDict)
24
33
  assign_formats: FlatFieldMap = dataclasses.field(default_factory=OrderedDict)
25
- #assign_ids: FlatFieldMap = dataclasses.field(default_factory=OrderedDict)
26
34
  assign_ids: Mapping[str, AssignIdConfig] = dataclasses.field(default_factory=OrderedDict)
35
+ #filter_eq: FlatFieldMap = dataclasses.field(default_factory=OrderedDict)
36
+ filter: list[FilterConfig] = dataclasses.field(default_factory=list)
37
+ omit_fields: list[str] = dataclasses.field(default_factory=list)
27
38
  split_by_newline: FlatFieldMap = dataclasses.field(default_factory=OrderedDict)
28
39
 
29
40
  def __setitem__(self, key, value):
@@ -65,6 +76,7 @@ def setup_process_config(
65
76
  for process_key in [
66
77
  'assign_constants',
67
78
  'assign_formats',
79
+ 'filter_eq',
68
80
  'split_by_newline',
69
81
  ]:
70
82
  dict_subprocess = dict_process.get(process_key)
@@ -14,7 +14,10 @@ import pandas as pd
14
14
 
15
15
  # local
16
16
 
17
- from . config import setup_config
17
+ from . config import (
18
+ FilterConfig,
19
+ setup_config,
20
+ )
18
21
  from . constants import (
19
22
  FILE_FIELD,
20
23
  INPUT_FIELD,
@@ -65,7 +68,7 @@ def load_json(
65
68
  data = json.load(f)
66
69
  if not isinstance(data, list):
67
70
  raise ValueError(f'Invalid JSON array data: {input_file}')
68
- ic(data[0])
71
+ #ic(data[0])
69
72
  rows = []
70
73
  for row in data:
71
74
  new_row = flatten(row)
@@ -103,9 +106,9 @@ def save_json(
103
106
  #)
104
107
  #ic(df.iloc[0])
105
108
  data = df.to_dict(orient='records')
106
- ic(data[0])
109
+ #ic(data[0])
107
110
  data = [nest(row) for row in data]
108
- ic(data[0])
111
+ #ic(data[0])
109
112
  with open(output_file, 'w') as f:
110
113
  json.dump(
111
114
  data,
@@ -205,12 +208,32 @@ def apply_fields_split_by_newline(
205
208
  new_row[f'{STAGING_FIELD}.{column}'] = value
206
209
  return new_row
207
210
 
211
+ def filter_row(
212
+ row: OrderedDict,
213
+ list_filters: list[FilterConfig],
214
+ ):
215
+ for config in list_filters:
216
+ value, found = search_column_value(row, config.field)
217
+ if config.operator == '==':
218
+ if not found:
219
+ return False
220
+ if str(value) != str(config.value):
221
+ return False
222
+ elif config.operator == '!=':
223
+ if str(value) == str(config.value):
224
+ return False
225
+ else:
226
+ raise ValueError(f'Unsupported operator: {config.operator}')
227
+ return True
228
+
208
229
  def convert(
209
230
  input_files: list[str],
210
231
  output_file: str | None = None,
211
232
  config_path: str | None = None,
212
233
  assign_constants: str | None = None,
213
234
  assign_formats: str | None = None,
235
+ str_filters: str | None = None,
236
+ str_omit_fields: str | None = None,
214
237
  pickup_columns: str | None = None,
215
238
  fields_to_split_by_newline: str | None = None,
216
239
  fields_to_assign_ids: str | None = None,
@@ -255,6 +278,29 @@ def convert(
255
278
  config.process.split_by_newline[dst] = src
256
279
  else:
257
280
  raise ValueError(f'Invalid split by newline: {field}')
281
+ if str_filters:
282
+ fields = str_filters.split(',')
283
+ for field in fields:
284
+ if '==' in field:
285
+ column, value = field.split('==')
286
+ config.process.filter.append(FilterConfig(
287
+ field = column,
288
+ operator = '==',
289
+ value = value,
290
+ ))
291
+ elif '!=' in field:
292
+ column, value = field.split('!=')
293
+ config.process.filter.append(FilterConfig(
294
+ field = column,
295
+ operator = '!=',
296
+ value = value,
297
+ ))
298
+ else:
299
+ raise ValueError(f'Invalid filter eq: {field}')
300
+ if str_omit_fields:
301
+ fields = str_omit_fields.split(',')
302
+ for field in fields:
303
+ config.process.omit_fields.append(field)
258
304
  if fields_to_assign_ids:
259
305
  setup_assign_ids(config, fields_to_assign_ids)
260
306
  if output_file:
@@ -301,16 +347,24 @@ def convert(
301
347
  new_flat_row = map_formats(new_flat_row, config.process.assign_formats)
302
348
  if config.map:
303
349
  new_flat_row = remap_columns(new_flat_row, config.map)
350
+ if config.process.filter:
351
+ if not filter_row(new_flat_row, config.process.filter):
352
+ continue
353
+ if config.process.omit_fields:
354
+ for field in config.process.omit_fields:
355
+ new_flat_row.pop(field, None)
304
356
  if not output_debug:
305
- new_flat_row.pop(STAGING_FIELD, None)
357
+ for key in list(new_flat_row.keys()):
358
+ if key.startswith(STAGING_FIELD):
359
+ new_flat_row.pop(key)
306
360
  new_flat_rows.append(new_flat_row)
307
361
  new_df = pd.DataFrame(new_flat_rows)
308
362
  df_list.append(new_df)
309
363
  all_df = pd.concat(df_list)
310
364
  #ic(all_df)
311
365
  ic(len(all_df))
312
- ic(all_df.columns)
313
- ic(all_df.iloc[0])
366
+ #ic(all_df.columns)
367
+ #ic(all_df.iloc[0])
314
368
  if output_file:
315
369
  ic('Saing to: ', output_file)
316
370
  saver(all_df, output_file)
@@ -1,2 +0,0 @@
1
- __version__ = "0.2.9"
2
- __version_tuple__ = (0, 2, 9)