Python Coding Academy
🐍 آموزش جامع Python — پست ۲۳۶
ساخت لایه دسترسی به داده با Repository Pattern در Python
در پروژههای کوچک ممکن است تمام Queryهای SQLite را داخل یک فایل بنویسیم؛ اما با بزرگتر شدن پروژه، نگهداری و تست کد دشوارتر میشود.
یکی از روشهای سازماندهی کد، Repository Pattern است.
در این الگو، عملیات مربوط به دریافت و ذخیره اطلاعات را در یک کلاس جداگانه قرار میدهیم.
🔹 ساختار پروژه
project/
├── database.py
├── user_repository.py
└── main.py
database.py مسئول ایجاد اتصال است.
user_repository.py عملیات مربوط به کاربران را مدیریت میکند.
main.py منطق اصلی برنامه را اجرا میکند.
🔹 فایل database.py
import sqlite3
def get_connection():
connection = sqlite3.connect("app.db")
connection.row_factory = sqlite3.Row
return connection
با row_factory میتوانیم مقادیر هر ردیف را با نام ستون نیز بخوانیم.
🔹 فایل user_repository.py
class UserRepository:
def __init__(self, connection):
self.connection = connection
def create_table(self):
self.connection.execute("""
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
)
""")
def add_user(self, name):
cursor = self.connection.execute(
"INSERT INTO users (name) VALUES (?)",
(name,)
)
return cursor.lastrowid
def get_all(self):
return self.connection.execute(
"SELECT id, name FROM users ORDER BY id"
).fetchall()
این کلاس مسئول اجرای Queryهای مربوط به کاربران است؛ اما خودش اتصال دیتابیس را ایجاد نمیکند.
🔹 فایل main.py
from contextlib import closing
from database import get_connection
from user_repository import UserRepository
with closing(get_connection()) as connection:
with connection:
users = UserRepository(connection)
users.create_table()
user_id = users.add_user("Ali")
print("New user ID:", user_id)
for user in users.get_all():
print(user["id"], user["name"])
خروجی نمونه:
New user ID: 1
1 Ali
اگر دیتابیس از قبل کاربر داشته باشد، شناسه جدید ممکن است عدد دیگری باشد.
🔹 چرا این روش مفید است؟
Queryها از منطق اصلی برنامه جدا میشوند.
کد قابلخواندنتر و نگهداری آن سادهتر میشود.
میتوانیم عملیات دیتابیس را مستقلتر تست کنیم.
در صورت تغییر ساختار ذخیرهسازی، تغییرات در یک بخش متمرکز میشوند.
⚠️ نکته مهم
Repository Pattern بهخودیخود تراکنش یا اتصال را مدیریت نمیکند. در مثال ما، main.py مسئول مدیریت تراکنش و بستن اتصال است.
همچنین در پروژههای بزرگتر میتوانیم اعتبارسنجی ورودیها، مدیریت خطاها و عملیات بیشتری مانند get_by_id() و delete_user() را به Repository اضافه کنیم.
🧠 خلاصه
main.py
↓
UserRepository
↓
SQLite
Repository عملیات دسترسی به داده را متمرکز میکند و منطق اصلی برنامه را از جزئیات Queryها جدا نگه میدارد.
🎯 تمرین
کلاس UserRepository را گسترش بده و متدی به نام get_by_id(user_id) بساز که کاربر موردنظر را با شناسه پیدا کند.
اگر کاربری با آن شناسه وجود نداشت، باید None برگردانده شود.
پست ۲۳۶ از دوره جامع Python 🐍
4 ·