DEV Community

Cover image for Orator ORM 的 Seeding 機制
Leon
Leon

Posted on • Originally published at editor.leonh.space

1

Orator ORM 的 Seeding 機制

之前寫過一篇〈初探 Orator ORM〉,有介紹了 Orator ORM 的基礎操作,而此篇文章就專門介紹 Orator ORM 的 seeding 機制,本篇的範例也都延續自〈初探 Orator ORM〉,還沒讀過的朋友請趕快手刀點擊閱讀。

阿湯哥手刀狂奔

來源:自由娛樂

Seeding

Seeding 用於在資料庫內建出一堆資料,這些資料可以是用於資料庫初始化的資料,例如郵遞區號,也可以是用於測試的假資料,而 Orator ORM 使用的是 Faker 套件當作假資料產生器。

Orator ORM 的 Seeding 操作

再次回顧一下在〈初探 Orator ORM〉文中的專案結構:

project1
├── app.db
├── oratordemo
│   ├── database.py
│   ├── __init__.py
│   ├── migrations
│   │   └── __init__.p
│   └── models
│        └── __init__.py
├── poetry.lock
└── pyproject.toml
Enter fullscreen mode Exit fullscreen mode

分別有放 migration 腳本檔的 migrations/ 和放 model 腳本檔的 models/,理所當然的 seeding 腳本就會放在 seeds/ 裡面,因此產生過 seeding 腳本之後的目錄結構就會長這樣:

project1
├── app.db
├── oratordemo
│   ├── __init__.py
│   ├── database.py
│   ├── config
│   │   └── __init__.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models
│   │   └── __init__.py
│   └── seeds
│        └── __init__.py
├── poetry.lock
└── pyproject.toml
Enter fullscreen mode Exit fullscreen mode

與 migrations/ 和 models/ 一樣,這個 seeds/ 不用手動建立,Orator ORM 會替我們代勞。

另一個新的 config/ 則是放 model factory 腳本的地方,後面會再提到。

建立 Seeding 腳本

(porject1) ~/project1/oratordemo> orator make:seed user_table_seeder

database_seeder created successfully.
user_table_seeder created successfully.
Enter fullscreen mode Exit fullscreen mode

進去 seeds/ 看一下,注意到除了預期的 user_table_seeder.py 外,Orator ORM 還另外建了個 database_seeder.py,這個 database_seeder.py 只會建立一次,關於這個檔案的作用我們後面會再提到,先關心 user_table_seeder.py:

from orator.seeds import Seeder

class UserTableSeeder(Seeder):

    def run(self):
        """
        Run the database seeds.
        """
        pass

Enter fullscreen mode Exit fullscreen mode

裡面只有一個空的 run() 函式,這個函式就是在跑 seeding 時會被呼叫的函式,函式內放的就是建立 User 資料的敘述,但架構上我們會把實際產生假資料的邏輯抽離,在這邊我們引入 model factory 的概念,顧名思義,model factory 就是實際產生假資料的「工廠」,而 xxx_seeder.py 則負責向工廠下單。

定義 Model Factory

建立 oratordemo/config/factories.py 檔案:

from orator.orm import Factory
from oratordemo.models.user import User

factory = Factory()

@factory.define(User)
def users_factory(faker):
    return {
        'name': faker.name(),
        'age': faker.random_int(min=1, max=115),
        'birthday': faker.date_of_birth(minimum_age=0, maximum_age=115).strftime('%Y-%m-%d')
    }
Enter fullscreen mode Exit fullscreen mode

這邊會帶入一個 Orator ORM 自行產生的 Faker 物件,而 Faker 的用法也頗直覺。Faker 可以產出的假資料有許多種類,可以閱讀 Faker 的文件了解。

有了 model factory,我們回到 seeder 寫向工廠下單的部份。

呼叫 Model Factory

把 user_table_seeder.py 加上呼叫 model factory 的部份:

from orator.seeds import Seeder
from oratordemo.config.factories import factory
from oratordemo.models.user import User

class UserTableSeeder(Seeder):

    factory = factory

    def run(self):
        """
        Run the database seeds.
        """
        self.factory(User, 50).create()
Enter fullscreen mode Exit fullscreen mode

從上面可以看出 seeder 和 model factory 的分工,model factory 負責實際的生產邏輯,而 seeder 負責向 model factory 下訂數量。

執行 Seeder

若要執行特定的 seeder,執行這樣的命令:

(project1) ~/project1> env PYTHONPATH='/home/leon/project1' orator db:seed --config=oratordemo/database.py --path=oratordemo/seeds/ --seeder=user_table_seeder

Are you sure you want to seed the database?:  (yes/no) [no] yes
Database seeded!
Enter fullscreen mode Exit fullscreen mode

會這麼落落長是有原因的,Orator ORM 在跑 seeder 內如果有 import 敘述會引發 ModuleNotFoundError 這個問題,因此必須多加一個環境變數讓 Python 能找到我們要 import 的模組。

若要執行一連串的 seeder,則可以把要跑的 seeder 定義在 database_seeder.py 內,這個檔案在初次建立 seeder 時會一併建立,目前還是空的,把它加上 call() 敘述來加入要跑的 seeder 們:

from orator.seeds import Seeder
from oratordemo.seeds.user_table_seeder import UserTableSeeder

class DatabaseSeeder(Seeder):

    def run(self):
        """
        Run the database seeds.
        """
        self.call(UserTableSeeder)
Enter fullscreen mode Exit fullscreen mode

如果前面跑 seeder 的命令,把指定特定 seeder 的參數拿掉,按照約定它就會去跑這支 database_seeder.py:

(project1) ~/project1> env PYTHONPATH='/home/leon/project1' orator db:seed --config=oratordemo/database.py --path=oratordemo/seeds/

Are you sure you want to seed the database?:  (yes/no) [no] yes

Seeded: UserTableSeeder
Database seeded!
Enter fullscreen mode Exit fullscreen mode

跑完可以去看一下資料庫,應該可以看到確實有 seeding 的資料在內。

結語

Orator ORM 沿襲了 ActiveRecord 的約定大於配置的風格,因此和 Laravel 的 Eloquent ORM 也有著類似的使用體驗,雖然在 Python 的世界 SQLAlchemy 由於歷史因素還是有較高的使用率,但對新專案來說 Orator ORM 是一個可以被認真考慮的選項。

覺得這篇文章對您有幫助請幫我們一鍵三連,拍手、訂閱、分享,小小的鼓勵是支撐我們分享的原動力,感謝讀完本文的您,也歡迎留下意見與我們交流。

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

Billboard image

Create up to 10 Postgres Databases on Neon's free plan.

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Try Neon for Free →

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay