# Báo cáo Tuần 2: ETL Pipeline với PySpark & Apache Iceberg

## 1. Mục tiêu công việc
- Xây dựng luồng dữ liệu (Data Pipeline) cơ bản bằng PySpark.
- Khai thác dữ liệu từ Data Lake (MinIO).
- Thực hiện làm sạch và chuẩn hoá dữ liệu.
- Lưu trữ dữ liệu ngược lại MinIO dưới định dạng Apache Iceberg (Table) và Parquet (File) phục vụ cho truy vấn và huấn luyện mô hình sau này.

## 2. Các công việc đã hoàn thành
1. **Dọn dẹp & Thiết lập môi trường**: 
   - Đã cấu hình và sử dụng Docker Compose với 2 dịch vụ chính là `minio_storage_week2` và `spark_env_week2`.
   - Các tệp tin dư thừa đã được xoá bỏ để tập trung vào mục tiêu chính.

2. **Quy trình ETL với PySpark** (`spark_etl.py`):
   - **Extract**: Đọc dữ liệu `creditcard.csv` từ MinIO sử dụng giao thức s3a (thông qua gói `hadoop-aws`).
   - **Transform**: 
     - **Làm sạch**: Loại bỏ các dòng trùng lặp (duplicates) và dòng chứa giá trị `Null`. Tổng số dòng sau khi làm sạch giảm từ 284.807 xuống 283.726.
     - **Chuẩn hóa**: Tính toán Mean và Standard Deviation để thực hiện Standard Scaling (thủ công qua phép biến đổi cột) cho 2 trường `Time` và `Amount`.
   - **Load**:
     - Lưu kết quả dưới dạng tệp `Parquet` vào thư mục `processed`.
     - Lưu kết quả vào **Apache Iceberg Table** tại `demo.db.creditcard_clean` trong thư mục `warehouse` trên MinIO.

3. **Notebook trực quan hoá** (`Week2_ETL_EDA.ipynb`):
   - Đã tạo Notebook chứa toàn bộ mã nguồn các bước trên. Notebook này có thể mở trực tiếp nghiệm thu nghiệm trên Jupyter Lab.

## 3. Các vấn đề đã giải quyết
- Đã khắc phục lỗi xung đột tên container MinIO trên Docker bằng cách loại bỏ container bị treo và chạy lại với cấu hình chuẩn.
- Đã khắc phục lỗi `TABLE_OR_VIEW_NOT_FOUND` của Apache Iceberg bằng cách đổi lệnh `replace()` thành `createOrReplace()`.

## 4. Kế hoạch tiếp theo
- Thiết lập Apache Airflow DAG (`creditcard_dag.py`) để chạy script `spark_etl.py` tự động theo lịch (Sau khi luồng Spark được xác nhận là đạt yêu cầu).
