name: 資料庫初始化 slug: "database-seeding" version: "1.1.0" displayName: "資料庫種子資料生成" summary: "為開發和測試填充逼真、可復現的測試資料到資料庫中,支援多種資料庫系統和資料模式。" description: 為開發、測試和預釋出環境填充真實、可重現的測試資料。 license: MIT metadata: author: AI Agent Skills Community version: 1.0.0
此技能使AI代理能夠生成並插入真實測試資料到資料庫中,用於開發、測試和預釋出環境。該代理使用確定性生成器或faker庫建立冪等種子指令碼,處理具有正確外部索引鍵順序的關聯資料,支援特定環境的種子配置檔案(最小開發資料與大規模負載測試),並確保種子可以重複執行而不會導致資料重複。
分析目標模式:檢查資料庫模式以識別所有表、其列、資料型別、約束(NOT NULL, UNIQUE, CHECK, 外部索引鍵)和關係。確定正確的插入順序以滿足外部索引鍵依賴——父表必須在子表之前被填充。
小蔥技能站7w4.net每天更新,海量AI技能等你發現。
設計種子資料策略:根據使用場景選擇適當的方法。使用固定種子的確定性資料來生成可重現的測試套件。使用基於faker的資料生成器建立看起來真實的開發資料。使用匿名化生產快照為需要真實資料分佈的預釋出環境生成資料。定義每個表的資料量。
生成種子指令碼:用專案語言(Python、JavaScript、SQL等)編寫匹配所有模式約束的種子指令碼。使用Faker庫或類似工具生成真實的姓名、郵箱、地址和日期。通過生成唯一值或使用基於序列的模式處理唯一性約束。將插入操作包裝在事務中以保證原子性。
確保冪等性:設計可安全重複執行的指令碼。使用INSERT ON CONFLICT DO NOTHING、UPSER模式或截斷後插入策略。在插入前檢查現有資料以避免重複或違反約束。
支援特定環境配置檔案:建立不同的種子配置檔案——本地開發使用小資料集(每表10-50條記錄),整合測試使用中等資料集(每表1,000-10,000條記錄),效能測試使用大數據集(每表10萬+條記錄)。通過環境變數或命令列引數控制配置檔案。
執行與驗證:在目標資料庫上執行種子指令碼,驗證行數是否符合預期,並確認通過檢查所有外部索引鍵引用現有行來保持關係完整性。記錄每個表的填充結果。
提供資料庫模式(或指向遷移檔案)並指定目標環境和所需資料量。代理將生成一個完整的種子指令碼,尊重所有約束和關係。您可以請求特定的資料特徵(例如,“包含來自多個時區的使用者”或“建立跨越過去12個月的訂單”)。
請求:為開發環境填充PostgreSQL資料庫中的使用者、產品和訂單資料。
"""seed.py — Seed development database with realistic test data."""
import random
from datetime import datetime, timedelta
from faker import Faker
import psycopg2
fake = Faker()
Faker.seed(42) # Deterministic output for reproducibility
random.seed(42)
DB_CONFIG = {
"host": "localhost",
"port": 5432,
"dbname": "dev_db",
"user": "dev_user",
"password": "dev_password",
}
NUM_USERS = 50
NUM_PRODUCTS = 30
NUM_ORDERS = 100
def seed():
conn = psycopg2.connect(**DB_CONFIG)
cur = conn.cursor()
# Seed users
user_ids = []
for _ in range(NUM_USERS):
cur.execute(
"""INSERT INTO users (email, password_hash, full_name, created_at)
VALUES (%s, %s, %s, %s)
ON CONFLICT (email) DO NOTHING
RETURNING id""",
(
fake.unique.email(),
fake.sha256(),
fake.name(),
fake.date_time_between(start_date="-2y", end_date="now"),
),
)
row = cur.fetchone()
if row:
user_ids.append(row[0])
# Seed products
product_ids = []
for i in range(NUM_PRODUCTS):
cur.execute(
"""INSERT INTO products (name, description, price, stock_quantity, sku)
VALUES (%s, %s, %s, %s, %s)
ON CONFLICT (sku) DO NOTHING
RETURNING id""",
(
fake.catch_phrase(),
fake.paragraph(nb_sentences=3),
round(random.uniform(9.99, 499.99), 2),
random.randint(0, 500),
f"SKU-{i+1:05d}",
),
)
row = cur.fetchone()
if row:
product_ids.append(row[0])
# Seed orders with order items
statuses = ["pending", "confirmed", "shipped", "delivered"]
for _ in range(NUM_ORDERS):
user_id = random.choice(user_ids)
status = random.choice(statuses)
items = random.sample(product_ids, k=random.randint(1, 5))
total = 0.0
cur.execute(
"""INSERT INTO orders (user_id, status, total_amount, shipping_address, ordered_at)
VALUES (%s, %s, 0, %s, %s) RETURNING id""",
(user_id, status, fake.address(), fake.date_time_between("-1y", "now")),
)
order_id = cur.fetchone()[0]
for pid in items:
qty = random.randint(1, 4)
price = round(random.uniform(9.99, 499.99), 2)
total += qty * price
cur.execute(
"""INSERT INTO order_items (order_id, product_id, quantity, unit_price)
VALUES (%s, %s, %s, %s)""",
(order_id, pid, qty, price),
)
cur.execute(
"UPDATE orders SET total_amount = %s WHERE id = %s", (round(total, 2), order_id)
)
conn.commit()
cur.close()
conn.close()
print(f"Seeded {len(user_ids)} users, {len(product_ids)} products, {NUM_ORDERS} orders.")
if __name__ == "__main__":
seed()
請求:為小型開發資料集建立一個純SQL種子檔案。
-- seed.sql — Idempotent seed data for local development
-- Run with: psql -U dev_user -d dev_db -f seed.sql
BEGIN;
-- Users
INSERT INTO users (id, email, password_hash, full_name, created_at) VALUES
(1, 'alice@example.com', 'hash_alice', 'Alice Johnson', '2024-03-15 09:00:00'),
(2, 'bob@example.com', 'hash_bob', 'Bob Martinez', '2024-05-20 14:30:00'),
(3, 'carol@example.com', 'hash_carol', 'Carol Chen', '2024-07-01 11:15:00'),
(4, 'dave@example.com', 'hash_dave', 'Dave Okafor', '2024-09-10 08:45:00'),
(5, 'eve@example.com', 'hash_eve', 'Eve Andersson', '2024-11-28 16:00:00')
ON CONFLICT (id) DO NOTHING;
-- Products
INSERT INTO products (id, name, description, price, stock_quantity, sku) VALUES
(1, 'Wireless Keyboard', 'Bluetooth mechanical keyboard', 79.99, 150, 'SKU-00001'),
(2, 'USB-C Hub', '7-in-1 USB-C docking station', 49.99, 300, 'SKU-00002'),
(3, 'Noise-Cancelling Headphones', 'Over-ear ANC headphones', 199.99, 75, 'SKU-00003'),
(4, '4K Monitor', '27-inch IPS 4K display', 399.99, 40, 'SKU-00004'),
(5, 'Laptop Stand', 'Adjustable aluminum stand', 34.99, 200, 'SKU-00005')
ON CONFLICT (id) DO NOTHING;
-- Orders
INSERT INTO orders (id, user_id, status, total_amount, shipping_address, ordered_at) VALUES
(1, 1, 'delivered', 129.98, '123 Oak St, Portland, OR 97201', '2024-12-01 10:00:00'),
(2, 2, 'shipped', 199.99, '456 Elm Ave, Austin, TX 78701', '2025-01-05 14:20:00'),
(3, 3, 'confirmed', 484.98, '789 Pine Rd, Seattle, WA 98101', '2025-01-10 09:30:00'),
(4, 1, 'pending', 49.99, '123 Oak St, Portland, OR 97201', '2025-01-12 16:45:00')
ON CONFLICT (id) DO NOTHING;
-- Order items
INSERT INTO order_items (id, order_id, product_id, quantity, unit_price) VALUES
(1, 1, 1, 1, 79.99),
(2, 1, 2, 1, 49.99),
(3, 2, 3, 1, 199.99),
(4, 3, 4, 1, 399.99),
(5, 3, 5, 1, 34.99),
(6, 4, 2, 1, 49.99)
ON CONFLICT (id) DO NOTHING;
-- Reset sequences to avoid conflicts with future inserts
SELECT setval('users_id_seq', (SELECT MAX(id) FROM users));
SELECT setval('products_id_seq', (SELECT MAX(id) FROM products));
SELECT setval('orders_id_seq', (SELECT MAX(id) FROM orders));
SELECT setval('order_items_id_seq', (SELECT MAX(id) FROM order_items));
COMMIT;
Faker.seed(42))以生成確定性資料,使測試結果可重現,並使種子輸出的差異具有意義。assert os.environ["ENV"] != "production")作為安全防護。fake.unique.email()或在生成值後附加計數器以避免重複。通過fake.unique.clear()在測試執行之間重置唯一追蹤器。這個技能質量較好,能幫助開發者快速掌握資料庫測試資料的生成方法。文件結構清晰,步驟明確,程式碼示例豐富實用,支援多種程式語言和資料庫。不過內容以文字說明為主,缺少可直接使用的示例檔案,對於新手來說可能需要更多實戰指導。總體適合需要為專案生成測試資料的開發者使用。