# Dựng demo khi khách chưa cấp dữ liệu: sinh dữ liệu giả tiếng Việt bằng Python và Faker

> Bạn có thể dùng tuần chờ cấp quyền truy cập dữ liệu để dựng một bộ dữ liệu giả có tên, địa chỉ Việt Nam, chạy lại lần nào cũng ra đúng kết quả cũ.

Bản gốc: https://fdetimes.net/vi/bach-khoa/thuc-hanh-du-lieu-gia-lap-faker-demo-khi-khach-chua-cap-du-lieu/

Thử hình dung tuần đầu bạn làm ở chỗ khách. Hợp đồng đã ký, cuộc họp kickoff đã xong, còn quyền truy cập database thì vẫn đang chờ bộ phận an ninh duyệt. Trong lúc đó, người phụ trách dự án phía khách muốn thứ Sáu này được xem một bản demo chạy được.

Người ta hay gặp đúng tình huống này: đã có tài liệu mô tả schema nhưng chưa có một dòng dữ liệu nào. Nếu ngồi chờ, bạn mất một tuần. Nếu dựng demo bằng vài dòng "Nguyen Van A" gõ tay, khách sẽ thấy ngay đó là đồ chơi.

Bài này hướng dẫn cách thứ ba: dùng Python và Faker sinh vài trăm khách hàng có tên, địa chỉ, công ty theo kiểu Việt Nam, chạy lại lần nào cũng ra đúng bộ dữ liệu đó. Bạn chỉ cần Python 3, pip và một terminal.

## Bạn sẽ dựng gì?

Kết quả cuối là một script `sinh_du_lieu.py` xuất ra hai file: `khach_hang.csv` và `don_hang.csv`. Bối cảnh giả định là một chuỗi bán lẻ muốn xem dashboard doanh thu theo khách. Đây là ví dụ đã giản lược để dễ học, schema thật của khách chắc chắn nhiều cột hơn.

Theo tài liệu chính thức, Faker là một gói Python chuyên sinh dữ liệu giả. README của dự án liệt kê các trường hợp dùng như khởi tạo database, stress test và ẩn danh hóa dữ liệu production. Demo chờ dữ liệu thật thuộc nhóm đầu tiên.

## Bước 1: cài đặt và ghi lại phiên bản

Tạo một virtualenv riêng cho demo rồi cài Faker:

```bash
pip install Faker
pip show Faker
```

**Kiểm tra:** `pip show` phải in ra một dòng `Version:`. Chép số phiên bản đó vào `requirements.txt` theo dạng `Faker==`. Lý do sẽ rõ ở bước 3, và đây cũng là lỗi người mới hay bỏ qua nhất.

## Bước 2: dữ liệu phải trông giống Việt Nam

Bạn có thể truyền locale vào `Faker` để nhận dữ liệu theo địa phương. Với khách Việt Nam, dùng `vi_VN`. Trang tài liệu của locale này có provider sinh địa chỉ Việt Nam, kèm các provider company, job và automotive.

```python
from faker import Faker

fake = Faker("vi_VN")
print(fake.name())
print(fake.address())
print(fake.company())
print(fake.job())
```

**Kiểm tra:** tên và địa chỉ in ra phải là tiếng Việt có dấu. Nếu thấy tên kiểu Mỹ, có thể bạn quên truyền locale, hoặc đang khởi tạo một biến `fake` khác ở chỗ khác trong code.

Chuyện này nghe nhỏ nhưng quyết định phản ứng của người xem. Một trưởng phòng kinh doanh thấy tên khách và địa chỉ quen thuộc trên dashboard sẽ bàn về con số. Thấy "John Smith, Springfield" thì họ bàn về chuyện demo trông lạ.

## Bước 3: seed để demo thứ Sáu giống demo thứ Năm

Bạn chạy thử tối thứ Năm, thấy khách hàng top 1 có doanh thu đẹp, chụp màn hình gửi trước cho khách. Sáng thứ Sáu chạy lại, top 1 đã thành người khác. Với một demo, đó là lỗi nặng.

Faker có phương thức `seed()` để gieo seed cho bộ sinh số ngẫu nhiên dùng chung. Theo README, cùng seed, cùng các phương thức, cùng phiên bản Faker thì ra cùng kết quả. README cũng nói rõ kết quả không được đảm bảo giống nhau giữa các bản vá, nên bước 1 mới bắt bạn pin phiên bản.

```python
import random
from faker import Faker

Faker.seed(2026)
random.seed(2026)
fake = Faker("vi_VN")
```

Ở đây có gieo thêm `random.seed` vì phần số tiền đơn hàng bên dưới dùng module `random` của Python. Tài liệu Python cho biết dùng lại một giá trị seed thì chuỗi số sẽ lặp lại giữa các lần chạy, miễn là không có nhiều thread chạy cùng lúc.

**Kiểm tra:** chạy script hai lần rồi so file đầu ra bằng `diff`. Không có dòng nào khác nhau thì đạt.

## Bước 4: không để email hay mã bị trùng

Dữ liệu ngẫu nhiên lâu lâu sẽ sinh trùng. Với cột tên, trùng không sao. Với cột làm khóa, như email đăng nhập hay mã đơn, trùng sẽ làm hỏng phép join và có khi làm demo sập ngay trước mặt khách.

Tài liệu lớp Faker cho biết gọi provider qua thuộc tính `.unique` thì giá trị trả về được đảm bảo không trùng. Khi cần sinh lại từ đầu, bạn xóa bộ nhớ đó bằng `fake.unique.clear()`.

```python
emails = [fake.unique.email() for _ in range(300)]
fake.unique.clear()
```

**Kiểm tra:** `len(set(emails)) == len(emails)` phải trả về `True`.

## Bước 5: script hoàn chỉnh

Ghép các bước lại. Bản dưới đây đã giản lược: mã khách đánh số tuần tự, số tiền là số nguyên ngẫu nhiên, chưa có phân phối theo mùa vụ.

```python
import csv
import random
from faker import Faker

Faker.seed(2026)
random.seed(2026)
fake = Faker("vi_VN")

khach = []
for i in range(1, 301):
khach.append({
"ma_kh": f"KH{i:04d}",
"ho_ten": fake.name(),
"email": fake.unique.email(),
"dia_chi": fake.address(),
"cong_ty": fake.company(),
})

with open("khach_hang.csv", "w", newline="", encoding="utf-8") as f:
w = csv.DictWriter(f, fieldnames=khach[0].keys())
w.writeheader()
w.writerows(khach)

with open("don_hang.csv", "w", newline="", encoding="utf-8") as f:
w = csv.writer(f)
w.writerow(["ma_don", "ma_kh", "so_tien"])
for j in range(1, 2001):
kh = random.choice(khach)["ma_kh"]
w.writerow([f"DH{j:05d}", kh, random.randint(50, 5000) * 1000])
```

**Kiểm tra:** mở hai file bằng công cụ dashboard bạn định demo, join theo `ma_kh`. Mọi đơn hàng phải khớp được với một khách hàng.

Có một biến thể đáng biết. Nếu tập khách của bạn có một phần là người nước ngoài, tài liệu Faker cho phép truyền một `OrderedDict` gồm các locale kèm trọng số để trộn theo tỉ lệ, chẳng hạn `OrderedDict([("vi_VN", 0.8), ("en_US", 0.2)])`. Tỉ lệ ở đây chỉ là ví dụ, nên lấy theo con số khách cung cấp.

## Ba lỗi khiến demo trên dữ liệu giả phản tác dụng

Lỗi đầu tiên là không pin phiên bản. Đồng nghiệp cài lại môi trường, kéo về một bản vá mới hơn, thế là "cùng seed" không còn ra cùng dữ liệu. Lỗi thứ hai là lấy module `random` để sinh token, mật khẩu hay bất cứ thứ gì dính tới bảo mật. Tài liệu Python nói rõ module này không dùng cho mục đích bảo mật.

Lỗi thứ ba khó thấy hơn: đặt tên cột theo ý mình. Nếu tài liệu schema của khách ghi `CUST_ID`, hãy đặt đúng `CUST_ID`. Như vậy, ngày có quyền truy cập, bạn chỉ phải đổi nguồn đọc dữ liệu chứ không phải sửa lại cả pipeline lẫn dashboard.

## Bài tập: tự làm bẩn dữ liệu của mình

Dữ liệu do chính bạn sinh thì sạch đến mức đáng ngờ. Để tập thói quen nghĩ về dữ liệu thật, hãy chèn đoạn dưới đây ngay trước khi ghi `khach_hang.csv`. Đây là mô phỏng giản lược: tỉ lệ 5% chỉ là con số giả định, và `CUST_ID` lấy theo ví dụ schema ở trên.

```python
for kh in khach:
kh["CUST_ID"] = kh.pop("ma_kh")
if random.random() < 0.05:
kh["email"] = ""
```

Nhớ đổi `ma_kh` thành `CUST_ID` ở phần sinh đơn hàng để phép join vẫn chạy. Vì `random` đã được gieo seed, các dòng bị xóa email sẽ giống nhau giữa các lần chạy.

**Kiểm tra:** mở lại dashboard. Nếu biểu đồ nào lỗi hay đếm sai khi email trống, bạn vừa tìm ra chỗ cần xử lý trước khi gặp dữ liệu thật.

**Điểm mấu chốt:** Dữ liệu giả giúp bạn có buổi demo đầu tiên, không giúp bạn hoàn thành dự án.

## Lúc nào dữ liệu giả hết tác dụng?

Một mẫu mô tả công việc FDE bản 2026 viết rằng người được tuyển sẽ làm việc cùng một đến ba khách hàng, bên trong hệ thống và trên dữ liệu của họ. Mẫu này cũng nêu một kiểu thất bại: demo chạy trên một sandbox dễ dãi, còn production thì không có sandbox như thế.

Vì vậy, nên coi bộ dữ liệu giả là thứ bạn sẽ bỏ đi. Nó giúp khách thấy hình dạng sản phẩm và giúp bạn kiểm tra logic join, tính tổng.

Nhưng nó không cho bạn biết dữ liệu thật bẩn đến mức nào, có bao nhiêu giá trị null, quyền truy cập bị chặn ở đâu. Trong buổi demo, bạn nên nói rõ dữ liệu là giả lập, rồi dùng chính buổi đó để xin quyền đọc một mẫu nhỏ dữ liệu thật.

Khi đọc JD, nếu thấy vị trí được mô tả là làm việc bên trong hệ thống và trên dữ liệu của khách, bạn nên chuẩn bị sẵn một câu chuyện về cách mình xoay xở trong giai đoạn chưa có quyền truy cập, vì rất có thể người phỏng vấn sẽ hỏi tới.

Trong CV, đừng ghi chung chung là "biết Faker". Hãy ghi bạn đã dựng demo trên dữ liệu giả lập tái lập được, giữ đúng schema của khách, rồi chuyển sang dữ liệu thật trong bao nhiêu ngày.

Người được đánh giá cao ở chỗ khách không phải người có bộ dữ liệu giả đẹp nhất. Đó là người xóa được bộ dữ liệu ấy sớm nhất.

**Thử ngay tuần này:**

- Chạy script mẫu trong bài với seed cố định, chạy hai lần rồi dùng diff so sánh hai file CSV để chắc chắn kết quả giống nhau
- Viết lại script cho một domain bạn quen (bán lẻ, logistics, ngân hàng), giữ tên cột y như trong tài liệu schema khách gửi
- Thêm vào CV hoặc README trên GitHub một dòng mô tả: dựng demo trên dữ liệu giả lập tái lập được trong lúc chờ cấp quyền dữ liệu thật

## Nguồn

- [Faker documentation](https://faker.readthedocs.io/en/master/)

- [Faker locale vi_VN providers](https://faker.readthedocs.io/en/master/locales/vi_VN.html)

- [joke2k/faker (README)](https://github.com/joke2k/faker)

- [Faker class documentation](https://faker.readthedocs.io/en/master/fakerclass.html)

- [random — Generate pseudo-random numbers (Python docs)](https://docs.python.org/3/library/random.html)

- [Forward Deployed Engineer Job Description (2026 Template)](https://vallettasoftware.com/blog/post/forward-deployed-engineer-job-description)
