python-table-processor 0.3.4__py3-none-any.whl → 0.3.6__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-table-processor
3
- Version: 0.3.4
3
+ Version: 0.3.6
4
4
  Summary: A table data processor
5
5
  Home-page: https://github.com/akivajp/python-table-processor
6
6
  License: MIT
@@ -1,23 +1,23 @@
1
- table_processor/__init__.py,sha256=7OSG5h81lLUUtcYTKQ2mDbsjJLsWCC6uFVXVJlfe8FE,52
1
+ table_processor/__init__.py,sha256=NnfhwEniUS8sdLDZO-0YfiWrkT_whyk4dJmhf1LDoHs,52
2
2
  table_processor/cli.py,sha256=uluf_VsBzq3Ldxh3ePGseSrv8--lI7huu-6RjDaHPPg,2170
3
- table_processor/commands/convert_tables.py,sha256=j25KL0zRl5ikrBk73jAkKn4rPmDq7SecChZxecDpILQ,2123
4
- table_processor/commands/merge_tables.py,sha256=Uu-hjfPh69Of0_OZrY8sY0oscpLSdK4jwJ_t1qgfPMg,1485
3
+ table_processor/commands/convert_tables.py,sha256=w4IZftSlrbt-BMPjldULT_616LSiNE3h7GmrFF7K5OM,2276
4
+ table_processor/commands/merge_tables.py,sha256=jryGU3gUx2TlGrI6FozGS_aJQvJQFco2LKwun6Uo9KY,1719
5
5
  table_processor/core/actions.py,sha256=GKUKzoPxUEuWSeuY-HsqFoS5Bdm99bjkRhuBgG1s_uk,23658
6
6
  table_processor/core/config.py,sha256=Z1s2r3y4oQXdbDCwIY_hYzoq6VRv7Sb3oUlfBCu13Lc,11646
7
7
  table_processor/core/constants.py,sha256=w-1TxtpXywb6Qh8M4YWuzcCHUvCjy5zJYxaXC3RQS6A,158
8
- table_processor/core/convert.py,sha256=cibzqJ5hHsfX_7qUz4kE2Gi-WH4UMqecBl3kSb4IVsY,11140
8
+ table_processor/core/convert.py,sha256=dzGcpBwJ5omiE8Pw-VmHnGoOqDyh1Rip6BiLdvdf3V8,11561
9
9
  table_processor/core/functions/assign_id.py,sha256=dA-wgZA7E01gbx8qGvo1PeMd3aq9PhMdyITzr3BKXIE,4204
10
10
  table_processor/core/functions/flatten_row.py,sha256=2l-s4YXgBM58IthpfVzd7L4EGUCekSi7ss5CaM_3MUU,686
11
- table_processor/core/functions/get_nested_field_value.py,sha256=vF4pH6nxR3-2bDfAvrMfHcPFNiS4MnGkXL8FdcScdIw,685
11
+ table_processor/core/functions/get_nested_field_value.py,sha256=ZEJi8XtDONoYmhPoqYpVZRGtEWvsfAksV4FXtkMAaq8,946
12
12
  table_processor/core/functions/nest_row.py,sha256=b5AKfxE39g-NOLranQRy0dfTZq-27Or8ZlgCB8N5kFs,640
13
13
  table_processor/core/functions/search_column_value.py,sha256=GscwLaMTORHFDhdCdjzdoy46UGyFHrGwDQA2b_tZhsQ,740
14
14
  table_processor/core/functions/set_flat_field_value.py,sha256=7-BgD2yEUGyBaFaIJ18bYv82Qdy0CN8NiC5ZtsAdv44,531
15
15
  table_processor/core/functions/set_nested_field_value.py,sha256=csO0v_nW94q-M9bNL91xR-TLHPXDDxnLK8gN-0LLd6k,595
16
16
  table_processor/core/functions/set_row_value.py,sha256=wlF_nVGZY74XCzd6pBJJyti62m6y0s1kc5Q6uq9jn8o,641
17
- table_processor/core/merge.py,sha256=Yc5OV9n1xV9QtgY4srl6Susd5cOKbuYseEtYuBampDw,4672
17
+ table_processor/core/merge.py,sha256=Sqnr-d7XCkRHvypExsHLboJBKxemPWnLNhKB0CuCPN8,5157
18
18
  table_processor/core/types.py,sha256=xNvy1vL1ei87kt-MgSfRJSllYrNKRo23pHtJA15DyLQ,2895
19
- python_table_processor-0.3.4.dist-info/LICENSE,sha256=1_Gn0I1neLPxDLfLiHEyxjDg-pbAra1p2iHEqutGS_c,1068
20
- python_table_processor-0.3.4.dist-info/METADATA,sha256=c9BCBmEomxvkfcU2FpuhGvFT2TM183wdYiCcDy4yQQA,1098
21
- python_table_processor-0.3.4.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
22
- python_table_processor-0.3.4.dist-info/entry_points.txt,sha256=lq97F6m51yZ93qmVIqkUHJfbILZuYLxrMWXSqrP4JpM,118
23
- python_table_processor-0.3.4.dist-info/RECORD,,
19
+ python_table_processor-0.3.6.dist-info/LICENSE,sha256=1_Gn0I1neLPxDLfLiHEyxjDg-pbAra1p2iHEqutGS_c,1068
20
+ python_table_processor-0.3.6.dist-info/METADATA,sha256=TgRGjK9lb7EFMdnyoZMffMiOz16SR2HEzc7w442DtvE,1098
21
+ python_table_processor-0.3.6.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
22
+ python_table_processor-0.3.6.dist-info/entry_points.txt,sha256=lq97F6m51yZ93qmVIqkUHJfbILZuYLxrMWXSqrP4JpM,118
23
+ python_table_processor-0.3.6.dist-info/RECORD,,
@@ -1,2 +1,2 @@
1
- __version__ = "0.3.4"
2
- __version_tuple__ = (0, 3, 4)
1
+ __version__ = "0.3.6"
2
+ __version_tuple__ = (0, 3, 6)
@@ -20,6 +20,7 @@ def run(
20
20
  output_debug = args.output_debug,
21
21
  verbose = args.verbose,
22
22
  ignore_file_rows = args.ignore_file_rows,
23
+ skip_header = args.skip_header,
23
24
  )
24
25
 
25
26
  def setup_parser(
@@ -77,4 +78,9 @@ def setup_parser(
77
78
  action='store_true',
78
79
  help='Output debug information',
79
80
  )
81
+ parser.add_argument(
82
+ '--skip-header',
83
+ action='store_true',
84
+ help='Skip header',
85
+ )
80
86
  parser.set_defaults(handler=run)
@@ -15,7 +15,8 @@ def run(
15
15
  keys=args.keys,
16
16
  allow_duplicate_keys=args.allow_duplicate_keys,
17
17
  ignore_not_found=args.ignore_not_found,
18
- output_file=args.output_file,
18
+ output_base_data_file=args.output_base_data_file,
19
+ output_modified_data_file=args.output_modified_data_file,
19
20
  )
20
21
 
21
22
  def setup_parser(
@@ -50,9 +51,13 @@ def setup_parser(
50
51
  help='Ignore not found',
51
52
  )
52
53
  parser.add_argument(
53
- '--output-file', '--output', '-o',
54
- metavar='OUTPUT_FILE',
54
+ '--output-base-data-file', '--output-base',
55
55
  required=False,
56
- help='Path to the output file.',
56
+ help='Path to output base data file',
57
+ )
58
+ parser.add_argument(
59
+ '--output-modified-data-file', '--output-modified',
60
+ required=False,
61
+ help='Path to output modified data file',
57
62
  )
58
63
  parser.set_defaults(handler=run)
@@ -64,12 +64,13 @@ def register_loader(
64
64
 
65
65
  def load(
66
66
  input_file: str,
67
+ **kwargs,
67
68
  ):
68
69
  ext = os.path.splitext(input_file)[1]
69
70
  if ext not in dict_loaders:
70
71
  raise ValueError(f'Unsupported file type: {ext}')
71
72
  loader = dict_loaders[ext]
72
- return loader(input_file)
73
+ return loader(input_file, **kwargs)
73
74
 
74
75
  dict_savers: dict[str, callable] = {}
75
76
  def register_saver(
@@ -93,16 +94,34 @@ def save(
93
94
  @register_loader('.csv')
94
95
  def load_csv(
95
96
  input_file: str,
97
+ **kwargs,
96
98
  ):
99
+ skip_header = kwargs.get('skip_header', False)
97
100
  # utf-8
98
101
  #df = pd.read_csv(input_file)
99
102
  # UTF-8 with BOM
100
- df = pd.read_csv(input_file, encoding='utf-8-sig')
103
+ if skip_header:
104
+ df = pd.read_csv(
105
+ input_file,
106
+ encoding='utf-8-sig',
107
+ header=None,
108
+ )
109
+ #new_column_names = [f'__values__.{i}' for i in df.columns]
110
+ new_column_names = [f'{i}' for i in df.columns]
111
+ df = df.rename(columns=dict(
112
+ zip(df.columns, new_column_names)
113
+ ))
114
+ else:
115
+ df = pd.read_csv(
116
+ input_file,
117
+ encoding='utf-8-sig',
118
+ )
101
119
  return df
102
120
 
103
121
  @register_loader('.xlsx')
104
122
  def load_excel(
105
123
  input_file: str,
124
+ **kwargs,
106
125
  ):
107
126
  #df = pd.read_excel(input_file)
108
127
  # NOTE: Excelで勝手に日時データなどに変換されてしまうことを防ぐため
@@ -123,6 +142,7 @@ def load_excel(
123
142
  @register_loader('.json')
124
143
  def load_json(
125
144
  input_file: str,
145
+ **kiwargs,
126
146
  ):
127
147
  with open(input_file, 'r') as f:
128
148
  data = json.load(f)
@@ -165,6 +185,7 @@ def save_json(
165
185
  @register_loader('.jsonl')
166
186
  def load_jsonl(
167
187
  input_file: str,
188
+ **kwargs,
168
189
  ):
169
190
  rows = []
170
191
  with open(input_file, 'r') as f:
@@ -274,6 +295,7 @@ def convert(
274
295
  action_delimiter: str = ':',
275
296
  verbose: bool = False,
276
297
  ignore_file_rows: list[str] | None = None,
298
+ skip_header: bool = False,
277
299
  ):
278
300
  ic.enable()
279
301
  ic()
@@ -306,11 +328,7 @@ def convert(
306
328
  if not os.path.exists(input_file):
307
329
  raise FileNotFoundError(f'File not found: {input_file}')
308
330
  base_name = os.path.basename(input_file)
309
- ext = os.path.splitext(input_file)[1]
310
- ic(ext)
311
- if ext not in dict_loaders:
312
- raise ValueError(f'Unsupported file type: {ext}')
313
- df = dict_loaders[ext](input_file)
331
+ df = load(input_file, skip_header=skip_header)
314
332
  # NOTE: NaN を None に変換しておかないと厄介
315
333
  df = df.replace([np.nan], [None])
316
334
  #ic(df)
@@ -15,11 +15,17 @@ def get_nested_field_value(
15
15
  if index < len(data):
16
16
  return data[index], True
17
17
  return None, False
18
+ if '.' in field:
19
+ field, rest = field.split('.', 1)
20
+ if field.isdigit():
21
+ index = int(field)
22
+ if index < len(data):
23
+ return get_nested_field_value(data[index], rest)
18
24
  if isinstance(data, dict):
19
25
  if field in data:
20
26
  return data[field], True
21
- if '.' in field:
22
- field, rest = field.split('.', 1)
23
- if field in data:
24
- return get_nested_field_value(data[field], rest)
27
+ if '.' in field:
28
+ field, rest = field.split('.', 1)
29
+ if field in data:
30
+ return get_nested_field_value(data[field], rest)
25
31
  return None, False
@@ -45,7 +45,8 @@ def merge(
45
45
  keys: list[str],
46
46
  allow_duplicate_keys: bool = False,
47
47
  ignore_not_found: bool = False,
48
- output_file: str | None = None,
48
+ output_base_data_file: str | None = None,
49
+ output_modified_data_file: str | None = None,
49
50
  ):
50
51
  ic.enable()
51
52
  ic()
@@ -53,7 +54,8 @@ def merge(
53
54
  ic(modification_files)
54
55
  ic(keys)
55
56
  dict_key_to_row = {}
56
- all_rows = []
57
+ all_base_rows = []
58
+ all_modified_rows = []
57
59
  list_ignored_keys = []
58
60
  num_modified = 0
59
61
  for previous_file in previous_files:
@@ -85,7 +87,7 @@ def merge(
85
87
  ic(index)
86
88
  raise ValueError(f'Duplicate key: {key}')
87
89
  dict_key_to_row[primary_key] = row
88
- all_rows.append(row)
90
+ all_base_rows.append(row)
89
91
  for modification_file in modification_files:
90
92
  if not os.path.exists(modification_file):
91
93
  raise FileNotFoundError(f'File not found: {modification_file}')
@@ -116,17 +118,21 @@ def merge(
116
118
  # dict_key_to_row[key].flat.update(row.flat)
117
119
  if primary_key not in dict_key_to_row:
118
120
  if ignore_not_found:
121
+ ic(primary_key)
122
+ ic(row.flat['__staging__.__file_row_index__'])
119
123
  list_ignored_keys.append(primary_key)
120
124
  continue
121
125
  ic(index)
122
- raise ValueError(f'Key not found: {key}')
126
+ raise ValueError(f'Key not found: {primary_key}')
123
127
  previous_row = dict_key_to_row[primary_key]
128
+ all_modified_rows.append(previous_row)
124
129
  #ic(previous_row)
125
130
  #ic(previous_row.flat)
126
131
  for key, value in row.flat.items():
127
132
  if key.startswith('__staging__.'):
128
133
  continue
129
- ic(key, value)
134
+ #ic(key)
135
+ #ic(key, value)
130
136
  set_row_value(previous_row, key, value)
131
137
  #set_row_value(previous_row, '指示追従性?', 'test')
132
138
  #set_row_value(previous_row, 'modified', True)
@@ -138,8 +144,11 @@ def merge(
138
144
  if ignore_not_found:
139
145
  ic(len(list_ignored_keys))
140
146
  ic(list_ignored_keys)
141
- if output_file:
142
- #all_df = pd.DataFrame(all_rows)
143
- all_df = pd.DataFrame([row.flat for row in all_rows])
144
- ic('Saving to: ', output_file)
145
- save(all_df, output_file)
147
+ if output_base_data_file:
148
+ all_df = pd.DataFrame([row.flat for row in all_base_rows])
149
+ ic('Saving to: ', output_base_data_file)
150
+ save(all_df, output_base_data_file)
151
+ if output_modified_data_file:
152
+ all_df = pd.DataFrame([row.flat for row in all_modified_rows])
153
+ ic('Saving to: ', output_modified_data_file)
154
+ save(all_df, output_modified_data_file)