کتابخانه 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 برای اعتبارسنجی ورودیها آماده کنم.
آیا این مطلب برای شما مفید بود ؟




