[UX] サブディレクトリ配下の CSV が silent に無視される/末尾スラッシュ差異の扱いが不明瞭
概要
/admin/list-csv → /admin/analyze が参照する _list_csv_files は、以下の実装により S3 プレフィックス直下の .csv ファイルだけを列挙する。サブディレクトリ配下の CSV はすべて無視される。
# lambda/adminwebbackend/app.py
def _list_csv_files(prefix: str) -> list[str]:
paginator = s3.get_paginator("list_objects_v2")
keys: list[str] = []
for page in paginator.paginate(Bucket=CSV_BUCKET_NAME, Prefix=prefix):
for obj in page.get("Contents", []):
key: str = obj["Key"]
if key.lower().endswith(".csv"):
filename = key[len(prefix):]
if filename and "/" not in filename: # ← サブディレクトリを除外
keys.append(key)
return keys
観察される問題
1. サブディレクトリが silent に無視される
たとえば以下のレイアウトで /admin/list-csv に testcase/F02/ を渡すと、archive/ 配下は列挙されず、利用者には「そこに CSV があるのに無視された」ことが一切見えない。
testcase/F02/
├── report_1.csv ← 拾われる
├── report_2.csv ← 拾われる
└── archive/
├── 2023_report.csv ← silent 無視
└── 2022_report.csv ← silent 無視
また Hive 風のパーティション配置はすべて silent 無視になる:
testcase/F03/
└── year=2024/
├── month=01/
│ └── sales.csv ← silent 無視
└── month=02/
└── sales.csv ← silent 無視
2. 直下に CSV が 0 件だとエラーメッセージが不親切
testcase/F01/ 直下に CSV がなく、a/foo.csv, b/bar.csv のようにサブディレクトリにだけある場合、_list_csv_files は空リストを返し、UI には「指定された prefix 配下に CSV ファイルが見つかりません」とだけ出る。実際には CSV はある(サブディレクトリに)。利用者は「無いと言われたが S3 で見ると確かにある」という状態に陥る。
3. プレフィックス末尾スラッシュ差異
testcase/F04-foo と testcase/F04-foo/ のどちらで呼んでも動くように見えるが:
len(prefix) で filename を切り出しているので、末尾スラッシュが無いと filename の先頭が / になり、"/" not in filename チェックを必ず落ちる(= 全部サブディレクトリ扱いで 0 件)
- 末尾スラッシュの正規化が
_list_csv_files 側にも _analyze_csv_file 側にも無い
期待される挙動
以下のいずれか、または組み合わせ:
- 再帰的に列挙し、サブディレクトリ配下の CSV も analyze 対象にする(データレイク互換、Hive パーティション対応)
- 直下優先のまま、サブディレクトリに CSV があったら UI に警告を表示する(「この prefix の下に 5 個 CSV がありますが、サブディレクトリ配下のため無視されました」)
- 末尾スラッシュの正規化を
_list_csv_files の先頭で行い、スラッシュ有無で挙動が変わらないようにする
- 直下 0 件 + サブディレクトリ有りのときは、エラーメッセージで「サブディレクトリ内の CSV は現在サポートされていません。prefix を
testcase/F01/a/ のように指定してください」とヒントを返す
再現手順(テストケース F シリーズとして生成予定)
本リポ(ogawsh fork の fork、サンプルデータ生成ツール)に以下のケースを追加予定:
- F01: 直下に CSV なし、サブディレクトリ
a/, b/ 配下にだけ CSV
- F02: 直下に CSV +
archive/ サブディレクトリにも CSV
- F03: Hive スタイル
year=2024/month=01/... のパーティション構造
- F04: 末尾スラッシュ差異(
testcase/F04-foo vs testcase/F04-foo/)
参考情報
- 関連ファイル:
lambda/adminwebbackend/app.py _list_csv_files, _group_csv_by_header
[UX] サブディレクトリ配下の CSV が silent に無視される/末尾スラッシュ差異の扱いが不明瞭
概要
/admin/list-csv→/admin/analyzeが参照する_list_csv_filesは、以下の実装により S3 プレフィックス直下の.csvファイルだけを列挙する。サブディレクトリ配下の CSV はすべて無視される。観察される問題
1. サブディレクトリが silent に無視される
たとえば以下のレイアウトで
/admin/list-csvにtestcase/F02/を渡すと、archive/配下は列挙されず、利用者には「そこに CSV があるのに無視された」ことが一切見えない。また Hive 風のパーティション配置はすべて silent 無視になる:
2. 直下に CSV が 0 件だとエラーメッセージが不親切
testcase/F01/直下に CSV がなく、a/foo.csv,b/bar.csvのようにサブディレクトリにだけある場合、_list_csv_filesは空リストを返し、UI には「指定された prefix 配下に CSV ファイルが見つかりません」とだけ出る。実際には CSV はある(サブディレクトリに)。利用者は「無いと言われたが S3 で見ると確かにある」という状態に陥る。3. プレフィックス末尾スラッシュ差異
testcase/F04-fooとtestcase/F04-foo/のどちらで呼んでも動くように見えるが:len(prefix)で filename を切り出しているので、末尾スラッシュが無いとfilenameの先頭が/になり、"/" not in filenameチェックを必ず落ちる(= 全部サブディレクトリ扱いで 0 件)_list_csv_files側にも_analyze_csv_file側にも無い期待される挙動
以下のいずれか、または組み合わせ:
_list_csv_filesの先頭で行い、スラッシュ有無で挙動が変わらないようにするtestcase/F01/a/のように指定してください」とヒントを返す再現手順(テストケース F シリーズとして生成予定)
本リポ(
ogawshfork の fork、サンプルデータ生成ツール)に以下のケースを追加予定:a/,b/配下にだけ CSVarchive/サブディレクトリにも CSVyear=2024/month=01/...のパーティション構造testcase/F04-foovstestcase/F04-foo/)参考情報
lambda/adminwebbackend/app.py_list_csv_files,_group_csv_by_header