Cấu hình cơ sở dữ liệu Peewee: Đồng bộ, bất đồng bộ, tự động khôi phục kết nối và quản lý pool

So sánh cơ sở dữ liệu đồng bộ và bất đồng bộ

Cấu hình kết nối cơ sở dữ liệu MySQL chung:

DB_SETTINGS = {
    'host': '127.0.0.1',
    'port': 3306,
    'user': 'root',
    'password': '123456',
    'database': 'ai_platform_cloud',
    'charset': 'utf8mb4'
}

Kết nối đồng bộ

Sử dụng lớp MySQLDatabase từ thư viện Peewee chuẩn:

from peewee import MySQLDatabase

sync_db = MySQLDatabase(**DB_SETTINGS)

Kết nối bất đồng bộ

Áp dụng peewee-async với lớp mở rộng hỗ trợ async/await:

from peewee_async import MySQLDatabase as AsyncMySQLDatabase

async_db = AsyncMySQLDatabase(**DB_SETTINGS)

Định nghĩa mô hình dữ liệu

Mô hình chung có thể dùng chung cho cả hai chế độ (với điều kiện sử dụng đúng instance database):

from peewee import Model, IntegerField, CharField

class Account(Model):
    id = IntegerField(primary_key=True)
    full_name = CharField(max_length=255)

    class Meta:
        # Sẽ được gán sau tùy vào chế độ sử dụng
        pass

# Gán database tương ứng khi khởi tạo
Account._meta.database = sync_db  # hoặc async_db

Tự động khôi phục kết nối khi mất kết nối

Thư viện playhouse.shortcuts.ReconnectMixin cung cấp cơ chế phát hiện và thiết lập lại kết nối tự động khi gặp lỗi mạng hoặc timeout.

Phiên bản đồng bộ

from peewee import MySQLDatabase
from playhouse.shortcuts import ReconnectMixin

class RobustMySQL(ReconnectMixin, MySQLDatabase):
    pass

robust_sync_db = RobustMySQL(**DB_SETTINGS)

Phiên bản bất đồng bộ

from peewee_async import MySQLDatabase as AsyncMySQLDatabase
from playhouse.shortcuts import ReconnectMixin

class RobustAsyncMySQL(ReconnectMixin, AsyncMySQLDatabase):
    pass

robust_async_db = RobustAsyncMySQL(**DB_SETTINGS)

Quản lý kết nối qua connection pool

Pool giúp tái sử dụng kết nối, giảm chi phí khởi tạo mới và tránh giới hạn hệ thống.

Pool đồng bộ

from playhouse.pool import PooledMySQLDatabase

pooled_sync_db = PooledMySQLDatabase(
    **DB_SETTINGS,
    max_connections=20,
    stale_timeout=300,      # đóng kết nối nếu không dùng trong 5 phút
    timeout=30              # chờ tối đa 30s khi lấy kết nối từ pool
)

Pool bất đồng bộ

from peewee_async import PooledMySQLDatabase as AsyncPooledMySQLDatabase

pooled_async_db = AsyncPooledMySQLDatabase(
    **DB_SETTINGS,
    max_connections=20,
    stale_timeout=300,
    timeout=30
)

Kết hợp cả hai: Pool + Tự phục hồi kết nối

Để đảm bảo độ tin cậy cao nhất, ta kế thừa từ cả ReconnectMixin và lớp pool tương ứng.

Phiên bản đồng bộ tích hợp

from playhouse.pool import PooledMySQLDatabase
from playhouse.shortcuts import ReconnectMixin

class SelfHealingPooledMySQL(ReconnectMixin, PooledMySQLDatabase):
    _shared_instance = None

    @classmethod
    def get_instance(cls):
        if cls._shared_instance is None:
            cls._shared_instance = cls(
                **DB_SETTINGS,
                max_connections=20,
                stale_timeout=300,
                timeout=30
            )
        return cls._shared_instance

db = SelfHealingPooledMySQL.get_instance()

Phiên bản bất đồng bộ tích hợp

from peewee_async import PooledMySQLDatabase as AsyncPooledMySQLDatabase
from playhouse.shortcuts import ReconnectMixin

class SelfHealingAsyncPooledMySQL(ReconnectMixin, AsyncPooledMySQLDatabase):
    _shared_instance = None

    @classmethod
    def get_instance(cls):
        if cls._shared_instance is None:
            cls._shared_instance = cls(
                **DB_SETTINGS,
                max_connections=20,
                stale_timeout=300,
                timeout=30
            )
        return cls._shared_instance

db = SelfHealingAsyncPooledMySQL.get_instance()

Thao tác truy vấn mẫu

Với mô hình Account đã định nghĩa ở trên:

  • Đồng bộ: accounts = list(Account.select().where(Account.id > 0))
  • Bất đồng bộ: accounts = await Account.objects.execute(Account.select().where(Account.id > 0))

Thẻ: peewee peewee-async mysql connection-pool reconnect-mixin

Đăng vào ngày 21 tháng 6 lúc 23:05