ویژگی تصویر

معرفی کتابخانه schematics در پایتون

  /  پایتون   /  کتابخانه schematics در پایتون
بنر تبلیغاتی الف

کتابخانه schematics یک ابزار سبک و قدرتمند برای مدل‌سازی، اعتبارسنجی و تبدیل ساختارهای داده در پایتون است. هدف آن ساده‌سازی تعریف مدل‌های داده‌ای (schema-like models) بدون نیاز به پایگاه داده است—مناسب برای پردازش ورودی API، خواندن پیکربندی، تبدیل داده‌ها و ETL.

ویژگی‌های کلیدی

  • تعریف مدل‌ها با فیلدهای تایپ‌شده (StringType، IntType، EmailType و …)
  • اعتبارسنجی خودکار و امکان نوشتن validatorهای سفارشی
  • تبدیل (coercion) ورودی‌ها به نوع مناسب و ارائه خروجی‌های ساده (primitive)
  • پشتیبانی از مدل‌های تو در تو، لیست‌ها و انواع پیچیده
  • سبک، مستقل از ORM و مناسب برای پروژه‌هایی که نیاز به یک لایه اعتبارسنجی/مدل‌سازی دارند

نصب

برای نصب ساده است:

pip install schematics

این دستور بسته schematics را از PyPI نصب می‌کند.

مثال ساده و توضیح کاربردی

from schematics.models import Model
from schematics.types import StringType, IntType, EmailType
from schematics.exceptions import DataError

class User(Model):
    name = StringType(required=True)
    age = IntType(default=0)
    email = EmailType(required=False)

data = {'name': 'علی', 'age': '30', 'email': 'ali@example.com'}
user = User(data)

try:
    user.validate()
except DataError as e:
    print('Errors:', e.to_primitive())

print(user.to_primitive())

توضیح: در این مثال یک مدل ساده User تعریف شده است. هنگام ساخت نمونه با دیکشنری ورودی، schematics تلاش می‌کند مقادیر را به نوع مناسب تبدیل کند (مثلاً رشته ’30’ به عدد 30) و سپس با فراخوانی user.validate() اعتبارسنجی را اجرا می‌کند. اگر خطایی وجود داشته باشد، DataError بالا می‌آید و با e.to_primitive() می‌توان ساختار خطا را چاپ کرد. در انتها user.to_primitive() خروجی‌ای از داده‌های تبدیل‌شده و قابل سریالایز شدن را برمی‌گرداند.

مدل‌های تو در تو و لیست‌ها

from schematics.types import ModelType, ListType

class Address(Model):
    street = StringType(required=True)
    city = StringType(required=True)

class Person(Model):
    name = StringType(required=True)
    addresses = ListType(ModelType(Address))

data = {
    'name': 'Sara',
    'addresses': [
        {'street': 'Vali Asr', 'city': 'Tehran'},
        {'street': 'Haft-e Tir', 'city': 'Tehran'}
    ]
}
person = Person(data)
person.validate()
print(person.to_primitive())

توضیح: ModelType و ListType اجازه می‌دهند مدل‌هایی تو در تو بسازید، که مناسب برای داده‌های پیچیده مثل آدرس‌ها یا عناصر انتشار یافته است. schematics به صورت بازگشتی فیلدها را پردازش و اعتبارسنجی می‌کند.

نوشتن validator سفارشی

from schematics.exceptions import ValidationError

class User(Model):
    name = StringType(required=True)
    age = IntType(default=0)

    def validate_age(self, data, value):
        if value < 0:
            raise ValidationError('age must be non-negative')
        return value

توضیح: برای هر فیلد می‌توانید متدی با نام validate_ تعریف کنید که ورودی و مقدار آن فیلد را می‌گیرد. اگر مقدار نامعتبر باشد، ValidationError پرتاب کنید. این روش خوانا و انعطاف‌پذیر است.

جدول: انواع رایج فیلدها

فیلدتوضیح
StringTypeرشته متن، می‌تواند max_length و regex داشته باشد
IntTypeاعداد صحیح، ممکن است به حداقل/حداکثر محدود شود
EmailTypeاعتبارسنجی قالب ایمیل
ModelTypeتو در تو کردن مدل‌ها
ListTypeلیستی از فیلدها یا مدل‌ها

بهترین شیوه‌ها و نکات حرفه‌ای

  • از تبدیل خودکار (coercion) آگاه باشید: schematics به صورت پیش‌فرض تلاش به تبدیل مقادیر می‌کند؛ اگر می‌خواهید رفتار سخت‌گیرانه‌تری داشته باشید، بهتر است validatorهای صریح اضافه کنید.
  • برای خطاها ساختار استاندارد خروجی انتخاب کنید تا در پاسخ‌های API قابل استفاده باشد (e.to_primitive() مفید است).
  • برای داده‌های پیچیده و بزرگی که نیاز به عملکرد بالا دارند، مقایسه‌ کنید: pydantic و marshmallow گزینه‌های دیگری هستند؛ pydantic سرعت و type-hinting بهتر دارد، اما schematics ساده و کم‌حجم است.
  • برای پیاده‌سازی‌های همزمان (concurrency)، دقت کنید که مدل‌ها حالت (state) را در خود نگه می‌دارند—اگر در چند نخ/روتین استفاده می‌کنید، نمونه‌های مجزا بسازید.

مثال بهینه‌سازی: استفاده از sanitize و default

from schematics.types import StringType

class Comment(Model):
    text = StringType(required=True)
    author = StringType(default='anonymous')

data = {'text': 'Hello', 'author': None}
c = Comment(data)
c.validate()
print(c.to_primitive())

توضیح: برخی مواقع می‌خواهید مقادیر None به مقدار پیش‌فرض تبدیل شوند یا فیلدها حذف شوند؛ کنترل این رفتار با default و validatorها انجام می‌شود. اگر مثلاً نمی‌خواهید None به عنوان مقدار معتبر پذیرفته شود، یک validator بنویسید که مقدار None را به مقدار پیش‌فرض یا خطا تبدیل کند.

موارد استفاده عملی

  • اعتبارسنجی ورودی‌های REST API در کنار فریم‌ورک‌های سبک
  • خواندن و اعتبارسنجی فایل‌های پیکربندی (YAML/JSON)
  • پایپلاین‌های ETL که نیاز به تبدیل داده‌ها بین منابع مختلف دارند
  • سرریز داده‌ها هنگام مهاجرت یا پاکسازی دیتابیس

مزایا و محدودیت‌ها

  • مزایا: سبک، ساده برای یادگیری، پشتیبانی از مدل‌های تو در تو و validation قابل توسعه
  • محدودیت‌ها: سرعت کمتر نسبت به libهای نوتر مثل pydantic، اکوسیستم پلاگین کمتر، و نگهداری کمتر فعال در برخی پروژه‌ها

جمع‌بندی

schematics برای پروژه‌هایی که به یک راهکار ساده و خوانا برای مدل‌سازی و اعتبارسنجی نیاز دارند گزینه عالی‌ای است. اگر به سرعت بسیار بالا یا Type-hinting ایستا نیاز دارید، بررسی pydantic نیز پیشنهاد می‌شود. در نهایت انتخاب به نیازهای پروژه، مقیاس و اولویت‌های تیم توسعه بستگی دارد.

در صورتی که بخواهید، می‌توانم مثال‌های بیشتری شامل یک API کامل با Flask یا FastAPI و استفاده از schematics برای اعتبارسنجی ورودی‌ها آماده کنم.

آیا این مطلب برای شما مفید بود ؟

خیر
بله
موضوعات شما در انجمن: