محمد، مهدی و پارسا به مسابقات ACM جهانی راهیافتهاند روز مسابقه هر تیم باید نام تیم خود را در فایل دیتابیس sqlite اضافه کند. ما باید کتابخانهای بنویسیم که کار را برای ارتباط با دیتابیس برای مهدی و دوستان ساده کند. این کد قرار است شبیه به یک ORM کار کند. در این سوال تنها کتابخانه sqlalchemy نصب شده است که میتوانید از آن استفاده کنید.
حال از شما خواسته شده که کلاس ORM را به صورت خواسته شده پیادهسازی کنید.
from exceptions import *
class ORM:
    def __init__(self, db_path):
        self.db_path = db_path
        self.create_database_if_not_exist()
    def create_database_if_not_exist(self):
        pass
    def create_table(self, table_path, table_name):
        pass
    def add_value(self, table_path, table_name, **values):
        pass
    def add_values(self, table_path, table_name, values):
        pass
    def remove_value(self, table_path, table_name, **values):
        pass
    def remove_values(self, table_path, table_name, values):
        pass
    def get_values(self, table_path, table_name, **filters):
        pass
تابع create_database_if_not_exist
create_database_if_not_existدر صورتی که فایل پایگاه داده تاکنون ساخته نشده آن را در آدرس db_path میسازد. نمونه db_path که به پوشه databases و پایگاه first.sqlite3 اشاره میکند (پوشه databases از قبل باید وجود داشته باشد):
db_path = r'databases/first.sqlite3''
تابع create_table
create_tableقرار است مسیر تعریف table و نام آن را دریافت کند و جدول را در پایگاه داده بسازد.
نحوه تعریف جدول در پایگاه داده به صورت زیر است.
# path : tables/users.py
from sqlalchemy import Integer, Column, String
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class User(Base):
    __tablename__ = 'user'
    name = Column(String, primary_key=True)
    family = Column(String, primary_key=True)
    likes = Column(Integer)
    order_fields = ['name', 'family']
    def to_json(self):
        return {
            'name': self.name,
            'family': self.family,
            'likes': self.likes
        }
در این صورت تابع را به صورت create_table('tables.user', 'User') صدا میزنیم. در صورت موجود بودن جدول در پایگاه داده، باید استثنای TableExistsException را raise کنید.
تابع add_value
add_valueمقدار جدید را میگیرد و در جدول مربوطه ذخیره میکند. نحوه صدا زدن این تابع به صورت
add_value('tables.user', 'User', name='mahdi', family='shokri', likes=3)
است. در صورت موجود بودن مقدار از قبل در جدول باید استثنای ValueExistException و در صورت هرگونه مشکل دیگر باید استثنای AddValueException را raise کنیم.
تابع add_values
add_valuesمقادیر جدید را میگیرد و در جدول مربوطه ذخیره میکند. نحوه صدا زدن این تابع به صورت
add_values('tables.user', 'User', [{'name': 'mahdi', 'likes': 3, 'family': 'shokri' }])
است. به ازای هر مورد در آرایه آن را به جدول اضافه میکند. توجه کنید که یا همه موارد اضافه شوند یا در صورت هرگونه مشکل برای هرکدام از موارد آرایه، باید استثنا AddValuesException را raise کنیم و پایگاه داده را به حالت قبل از این دستور، rollback کنیم.
تابع remove_value
remove_valueمقداری را میگیرد و بر اساس آرگومانها موارد را فیلتر و حذف میکند. مثلا
add_value('tables.user', 'User', name='mahdi')
تمام افرادی که نامشان mahdi است را حذف میکند. در صورت نبودن سطری برای حذف شدن در جدول یا هرگونه مشکل دیگر باید استثنای RemoveValueException را raise کند.
تابع remove_values
remove_valuesآرایهای از فیلترها میگیرد و به ازای هر کدام از فیلترها، موارد مربوط به آن فیلتر را که در جدول مطابقت دارند حذف میکند.
add_value('tables.user', 'User', [{'name': 'mahdi'}, {family': 'mohammadi'}])
به ازای هر کدام از موارد در آرایه حداقل باید یک سطر برای حذفشدن وجود داشته باشد در غیر این صورت استثنای RemoveValuesException بازگردانده شود.
تابع get_values
get_valuesمقادیر فیلتر را دریافت میکند و نتیجهای را به صورت json باز میگرداند. مثلا اگر تابع
get_values('tables.user', 'User', name='mahdi')
را صدا بزنیم تمام سطرهای جدول که name در آنها mahdi باشد را برمیگرداند. توجه کنید که ترتیب موارد در خروجی json باید بر اساس order_fields در تعریف جدول (در اینجا User) باشد.
[
  {
     'name': 'mahdi',
     'family': 'shokri',
     'likes': 4
  },
  {
     'name': 'mahdi',
     'family': 'sorkhi',
     'likes': 2
  }
]
توجه: هر جدولی که برای تست به شما کد شما داده شود، حتما دارای تابع to_json() است و نیازی نیست شما آن را تبدیل به json کنید.
نکات
- میتوانید فایل اولیه این سوال را از این لینک دریافت کنید.
 - تابع 
get_valueنباید مقداری را چاپ کند، بلکه باید مقادیر مورد نظر را بازگرداند. - شما میتوانید با پیادهسازی این سوال به صورت بخشبخش نمره بگیرید.
 - در صورت تمایل، میتوانید علاوهبر کلاس خواستهشده، کلاسها و تابعهای کمکی دیگری نیز در فایل 
orm.pyپیادهسازی کنید. 
نحوه ارسال
شما باید کلاس ORM موجود در فایل orm.py را تکمیل و سپس این فایل را ارسال کنید.
ارسال پاسخ برای این سؤال