Seeding
原意為播種,在這裡指的是批次建假資料,或是初始資料。假資料用於模擬真實的環境,供團隊成員去感受或模擬實際上線的使用,不過如果是單元測試的話,則與 seeding 的假資料無關,單元測試的假資料會在該單元測試的程式內有針對性的建立與消除,不會與 seeding 的假資料混用。
Seeding 指令
- 執行全部 seeder:
craft seed:run
。 - 執行特定 seeder,以 Transaction model 為例:
craft seed:run Transaction
。 - 建立 seeder,以 Transaction model 為例:
craft seed Transaction
。
範例
如果有用 craft auth
建立過用戶認證系統的話,這個指令也幫我們建了一套 User 物件的 seeder 範例,在實做我們的 seeder 前先看看範例的做法。
從 databases/seeds/database_seeder.py 開始看起:
"""Base Database Seeder Module."""
from orator.seeds import Seeder
from .user_table_seeder import UserTableSeeder
class DatabaseSeeder(Seeder):
def run(self):
"""Run the database seeds."""
self.call(UserTableSeeder)
前面提到過的 craft seed:run
就會執行這支看起來很空的 database_seeder.py,再透過裡面的 call()
來呼叫要被執行的 seeder。可以看到目前只有一個 UserTableSeeder,讓我們繼續看下去。
來看 database/seeds/user_table_seeder.py:
"""User Table Seeder.
You can run this seeder in order to generate users.
- Each time it is ran it will generate 50 random users.
- All users have the password of 'secret'.
- You can run the seeder by running: craft seed:run.
"""
from orator.seeds import Seeder
from app.User import User
from config.factories import factory
class UserTableSeeder(Seeder):
def run(self):
"""
Run the database seeds.
"""
factory(User, 50).create()
一樣很空,只是叫工廠幫我們做五十個 User 出來,至於具體工廠怎麼做出 User,從 config.factories 繼續追下去。
工廠在 config/factories.py:
from orator.orm import Factory
from app.User import User
from string import ascii_uppercase
factory = Factory()
def users_factory(faker):
return {
'name': faker.name(),
'email': faker.email(),
'password': '$2b$12$WMgb5Re1NqUr.uSRfQmPQeeGWudk/8/aNbVMpD1dR.Et83vfL8WAu', # == 'secret'
}
factory.register(User, users_factory)
先看最下面註冊工廠方法的敘述:User 的工廠方法使用 users_factroy()
。users_factory()
接受一個 faker
參數,這個參數是 Faker 的一個實例,但不用自己產生,Orator 在呼叫工廠方法時會自己幫我們產生 Faker 實例並餵入。
Faker 是個產出假資料的包,在專案建立時應該就會被裝起來。Faker 的使用也很直白,看上面的範例都可以望文生義,想更深入了解可以去讀 Faker 文件。
有了這樣的工廠方法,便可應用於 seeding 與單元測試,它們都可以共用這些工廠方法,不用重複造輪子。
建立 Seeder
在此以 Transaction model 為例,建立 seeder 與相關的工廠方法。
建立 Seeder 檔案:
$ craft seed Transaction
建立 Transaction 的 factory 方法,編輯 config/factories.py,加入相關敘述:
from app.Transaction import Transaction
from string import ascii_uppercase
def transactions_factory(faker):
return {
'user_id': faker.random_int(min=1, max=User.max('id')),
'date': faker.date_this_decade(after_today=True),
'amount': faker.random_int(),
'receipt_number': faker.bothify(text="??-########", letters=ascii_uppercase),
'description': faker.sentence(),
}
factory.register(Transaction, transactions_factory)
基本就是抄改 users_factory()
。
工廠方法完成後,回到 Transaction seeder 檔案,設定工廠製造數量。編輯 databases/seeds/transaction_table_seeder.py:
from orator.seeds import Seeder
from app.Transaction import Transaction
from config.factories import factory
class TransactionTableSeeder(Seeder):
def run(self):
"""
Run the database seeds.
"""
factory(Transaction, 1000).create()
基本上也是抄改。
工廠有了,製作數量設定了,再來讓 Transaction seeder 也會和其它 seeder 一起被執行,在 databases/seeds/database_seeder.py 加入這行:
self.call(TransactionTableSeeder)
最後實際跑一次 seeder:
$ craft seed:run
跑完可以進資料庫看一下是不是如預期的建了這些假資料。