Saya rasa salah satu skill data engineer yang dikurang mendapat perhatian adalah database atau SQL tuning. Ia adalah skill yang sangat penting jika anda terlibat dalam data pipeline yang mempunyai sifat sensitif masa (time sensitive). Tapi rencana hari ini bukan mengenai SQL tuning ya.
Ia lebih kepada cabaran yang saya hadapi untuk menjana data palsu (dummy data) dalam table-table. Ada satu package python yang sering digunakan untuk menjana data palsu ini iaitu Faker. Jika anda ingin menjana data untuk satu sahaja table saya sarankan anda mengggunkan package ini table-faker.
Untuk tujuan tuning, saya ingin mencuba menjana 2 tables: customers
dan orders
table. Jika hanya menggunakan faker atau table-faker yang asas kita tidak dapat membuat relationship antara dua table ini. Jadi dengan itu saya menghasilkan solusi ini.
Seperti biasa mari kita cipta table yang berkaitan:
customers
create table customers
(
customer_id varchar(256) PRIMARY KEY,
name varchar(256),
email varchar(256)
);
orders
create table orders
(
order_id varchar(256) PRIMARY KEY,
customer_id varchar(256),
order_date timestamp,
amount numeric
);
Skrip Data Palsu (Dummy Data)
Kita install dulu package Faker dan Pandas
pip install Faker
pip install pandas
Asas algorithm untuk menjana 2 table ini adalah
Jana data customers
Jana data orders berdasarkan customers tables (dengan menggunakan customer_id sebagai key)
Jana SQL statement
Untuk menjana maklumat customers, berikut adalah skrip python:
import uuid
import pandas as pd
from faker import Faker
# Initialize Faker
fake = Faker()
# Number of records to generate
num_customers = 100
num_orders = 500
# Generate customers
customers = []
for _ in range(num_customers):
customer_id = str(uuid.uuid4())
name = fake.name()
address = fake.address()
email = fake.email()
customers.append({
"customer_id": customer_id,
"name": name,
"email": email
})
# Convert to DataFrame
customer_df = pd.DataFrame(customers)
Daripada skrip di atas, saya telah set jumlah customers
sebanyak 100 dan jumlah orders
sebanyak 500.
Saya telah menggunakan uuid sebagai key customer_id
. Dengan menggunakan Faker package saya menjana maklumat di bawah:
Customer Name - dengan
fake.name()
Address - dengan
fake.address()
Email - dengan
fake.email()
Sebenarnya banyak lagi fake data yang boleh digunakan. Anda juga boleh memilih lokaliti data ( contohnya: Indonesia atau India) .
Untuk menjana maklumat orders pula, berikut adalah skrip python:
# Generate orders
orders = []
for _ in range(num_orders):
order_id = str(uuid.uuid4())
customer_id = customer_df.sample(n=1).iloc[0]['customer_id']
order_date = fake.date()
amount = round(fake.random_number(digits=5, fix_len=True) / 100, 2)
orders.append({
"order_id": order_id,
"customer_id": customer_id,
"order_date": order_date,
"amount": amount
})
# Convert to DataFrame
order_df = pd.DataFrame(orders)
Untuk orders
pula, saya menggunakan fake.date()
untuk order_date
customer_id pula saya ambil daripada dataframe customers_df
tadi.
Kemudian kita ubah data dalam dataframe ke SQL INSERT statement
# Function to convert DataFrame to SQL insert statements
def df_to_sql_insert(df, table_name):
columns = ', '.join(df.columns)
sql_statements = []
for _, row in df.iterrows():
values = ', '.join([f"'{str(x)}'" if isinstance(x, str) else str(x) for x in row.values])
sql_statement = f"INSERT INTO {table_name} ({columns}) VALUES ({values});"
sql_statements.append(sql_statement)
return sql_statements
Kemudian kita tuliskan INSERT statement tersebut dalam SQL file
def write_sql_to_file(sql_statements, file_path):
with open(file_path, 'w') as file:
for statement in sql_statements:
file.write(statement + '\n')
print(f"SQL statements have been written to {file_path}")
# Generate SQL insert statements
customer_insert_statements = df_to_sql_insert(customer_df, 'customers')
order_insert_statements = df_to_sql_insert(order_df, 'orders')
# Print sample insert statements
print("Customer Insert Statements")
for stmt in customer_insert_statements[:5]:
print(stmt)
print("\nOrder Insert Statements")
for stmt in order_insert_statements[:5]:
print(stmt)
customers_file_path = 'customers_data.sql'
orders_file_path = 'orders_data.sql'
write_sql_to_file(customer_insert_statements, customers_file_path)
write_sql_to_file(order_insert_statements, orders_file_path)
File yang dihasilkan adalah seperti berikut
customers
orders
Data yang dihasilkan setelah saya run SQL di atas adalah seperti berikut
select c.customer_id, count(o.order_id) total_order, sum(o.amount) total_amount
from customers c
LEFT JOIN orders o on c.customer_id = o.customer_id
group by c.customer_id;
Hasilanya.
Selamat mencuba!
Anda boleh muat turun playbook penuh di sini
Rujukan