Tạo dữ liệu giả (dummy data) để test bằng Faker

Faker là một thư viện rất nổi tiếng để tạo dữ liệu giả, với rất nhiều kiểu dữ liệu cho các vấn đề khác nhau như người dùng, công việc, thẻ ngân hàng, ..v..v.. Khi sử dụng faker bạn không cần phải đắn đo suy nghĩ nên viết script tạo dữ liệu giả như thế nào vì phần lớn đều đã có sẵn trong thư viện.

Faker được viết trên nhiều nền tảng như JS, python, R,… Trong bài viết dưới mình sẽ hướng dẫn các bạn cách sử dụng faker cơ bản trong python.

Tạo dữ liệu giả (dummy data) để test bằng Faker

Cài đặt Faker

Để sử dụng faker đầu tiến chúng ta phải cài đặt thư viện này trước. Nếu trên máy các bạn đã có python chỉ cần chạy.

Bạn có thể tham khảo thêm về faker trên pypi tại đây: https://pypi.org/project/Faker/

pip install Faker

Khái niệm

Faker class

Sau khi cài đặt faker, chúng ta có thể sử dụng faker ngay, hãy chạy lệnh này trong python.

import faker

fake = faker.Faker()
fake.name()
# "'Jason Smith'"

sau khi chạy lệnh này chúng ta có thể thấy class Faker sau khi được khởi tạo có thể tạo ra 1 tên người bất kì khi dùng method name().

Method name này thực ra thuộc một provider trong bộ các providers của thư viện faker. Truy cập vào link sau bạn sẽ thấy method name() thuộc vào provider mang tên là person.

https://faker.readthedocs.io/en/master/providers/faker.providers.person.html#faker.providers.person.Provider.name

Provider class

Provider là một class để tạo ra thêm các method tạo data cho Faker class. Bạn nhìn vào ví dụ bên dưới sẽ hiểu.

Đầu tiên bạn thử chạy script dưới đây.

import faker

fake = faker.Faker()
fake.generate_branch()
# AttributeError: 'Generator' object has no attribute 'generate_branch'

Ngay lập tức sẽ xuất hiện lỗi vì không tồn tại method generate_branch.

Sau đó chúng ta hãy thử khởi tạo BranchProvider theo mẫu ở dưới, trong class provider này có một method generate_branch và bạn hãy thử chạy lại xem sao nhé.

from faker.providers import BaseProvider
from faker import Faker

class BranchProvider(BaseProvider):
    def generate_branch(self) -> str:
        branches = ['TPHCM', 'Nha Trang', 'Ha Noi', 'Can Tho', 'Da Nang']
        return random.choice(branches)


fake = Faker()
fake.add_provider(BranchProvider)
fake.generate_branch()
# "'Can tho'"

Như vậy mặc dù ban đầu Faker class không hề có method generate_branch, tuy nhiên sau khi chúng ta add class BranchProvider vào, các method thuộc class này đều được thêm vào class Faker và có thể gọi được từ class Faker. Rất tiện lợi khi bạn muốn tạo thêm một provider hay một method để tạo ra data giả mới mà đang không có sẵn trong các provider tiêu chuẩn (Standard Providers).

Để xem hết tất cả các providers tiêu chuẩn và các methods của chúng, bạn có thể vào link dưới đây.

https://faker.readthedocs.io/en/master/providers.html

Sau khi nắm rõ 2 khái niệm Faker Class và Provider Class chúng ta có thể đại khái viết một chương trình để tạo ra data giả rồi đó, bắt đầu thôi.

Thực hành

Mình sẽ không viết tuần tự các bước mà sẽ paste toàn bộ code của chương trình vào sau đó giải thích từng phần.

YÊU CẦU: Viết một script tạo ra data thông tin giả của nhân viên của một công ty giả định, có nhiều trụ sở , các nhân viên này tên được lưu theo first name last name và công việc. Mã nhân viên công ty là một dãi 6 chữ viết hoa từ A->Z. Dữ liệu được chia làm 7 phần bằng file csv, và mỗi file có 100 dòng bao gồm header.

Code:

import csv
import random
import string
import os

from typing import Callable, Any
from faker import Faker
from faker.providers import BaseProvider


class RandomChar(BaseProvider):
    def generate_random_id(self) -> str:
        return ''.join(random.choice(string.ascii_uppercase) for x in range(6))


class BranchProvider(BaseProvider):
    def generate_branch(self) -> str:
        branches = ['TPHCM', 'Nha Trang', 'Ha Noi', 'Can Tho', 'Da Nang']
        return random.choice(branches)


def person_data_generator(faker: Faker) -> list[str]:
    return [faker.first_name(),  # random first name
            faker.last_name(),  # random last name
            faker.job(),  # random job
            faker.generate_random_id(), # create id
            faker.generate_branch()]  # create branch


def generate_csv(filename: str,
                 row_num: int,
                 generator: Callable[[Faker], list[Any]],
                 faker: Faker,
                 header: list[str]) -> None:
    os.makedirs(os.path.dirname(filename), exist_ok=True)
    with open(filename, 'w', newline='') as csvfile:
        writer = csv.writer(csvfile)
        writer.writerow(header)
        for n in range(1, row_num):
            writer.writerow(generator(faker))


def fake_data_plan() -> None:
    """
    This will generate data that into a csv folder with 7 different part, 100 line for each part
    :return:
    """
    fake: Faker = Faker()
    fake.add_provider(RandomChar)
    fake.add_provider(BranchProvider)
    for page in range(1, 8):
        generate_csv(filename=f'data_nhan_vien/danh_sach_nhanvien_so_{page}.csv',
                     row_num=100,
                     generator=person_data_generator,
                     faker=fake,
                     header=['first_name', 'last_name', 'job', 'employee_code','branch'])


if __name__ == '__main__':
    fake_data_plan()

Giải thích

person_data_generator

Chúng ta sẽ tạo nên mỗi dòng dữ liệu bằng function person_data_generator, function này sẽ trả về một list tương ứng với một dòng dữ liệu trong file csv. Ngoài ra chúng ta sử dụng một số tính năng của faker như sau. Function này phải được input một Faker class.

RandomChar Provider và BranchProvider

Chúng ta sử dụng 3 methods của Standard Providers là first_name, last_name, job cho các yêu cầu về họ tên cho function person_data_generator. Do không có provider đạt yêu cầu về “chi nhánh” (giả định chi nhánh tên Việt Nam) và mã số nhân viên nên chúng ta phải bổ sung thêm 2 providers cho chi nhánh và id. Hai providers này chính là RandomChar và BranchProvider.

generate_csv

Function này để tạo ra file csv từ một function generator (mà ở ví dụ này là person_data_generator). Ngoài ra function này còn nhận thêm header và số dòng của file.

fake_data_plan

Generate_csv chỉ tạo một file, chúng ta cần tạo ra 7 files như đề bài ngoài ra còn có thể thêm thắt một chút cho đẹp.

Kết quả sau khi chạy code

Sau khi chạy code chúng ta đã có danh sách nhân viên đúng theo yêu cầu của đề bài. Hãy cùng xem mẫu dữ liệu của 1 file nhé.

first_name,last_name,job,employee_code,branch
Eduardo,Barr,Make,USVLZG,Da Nang
Laura,Vega,"Engineer, production",WAOPHF,Can Tho
Juan,George,Environmental education officer,XPDATV,Da Nang
Mary,Lawson,Child psychotherapist,LIAMVT,Ha Noi
John,Garrison,Warden/ranger,AMMTEX,Can Tho
Laura,Farley,"Engineer, civil (consulting)",OYHYIP,TPHCM
Alicia,Wright,Sales promotion account executive,XTSNQW,Ha Noi
Rita,Thomas,"Conservator, museum/gallery",OOVWWN,Da Nang
Bailey,Jenkins,Musician,OXUJBD,Can Tho
Timothy,Randolph,"Merchandiser, retail",ZNEIYZ,Da Nang
Kristen,Maynard,"Producer, television/film/video",LWZCDW,Nha Trang
John,Manning,"Teacher, English as a foreign language",GXTSAV,TPHCM
Anthony,Andrade,Clinical cytogeneticist,JLPPDP,TPHCM
Mary,Sparks,"Scientist, research (medical)",YUJTOL,Ha Noi
Marilyn,Allen,Fitness centre manager,RQCJPH,Can Tho
Wanda,Thompson,Dramatherapist,ENECZB,Da Nan.............

Kết bài

Đó là cách bạn có thể sử dụng faker để tạo data giả dùng để test hoặc làm bất cứ thứ gì bạn muốn. Bạn có thể sửa lại hàm generate_csv thành insert_sql hoặc một tính năng khác để có thể tạo data giả trên các server sql hay bất kì nơi nào. Mình thì dùng faker vì nó soặn sẵn các format data thường dùng trong các trường hợp. Cảm ơn các bạn đã đón đọc.

Support Tuan | Analytic

Trả lời