یکی از راه های اتصال و کار با دیتابیسها استفاده از ORM (object-relational mappe) ها هستش. یکی از این ابزارها برای زبان پایتون Alchemy است.
خب برای شروع و استفاده از Alchemy لازم است که موارد زیر نصب بشه: ( و مثل هر پروژه پایتونی دیگه بهتره که از virtualenv and requirements.txt استفاده کنید)
بعد از نصب موارد بالا (pip install -r requirements.txt) در فولدر پروژه تون (همون فولدری که app.py قرار داره) یک فایل بنامdb.py بسازید (نام این فایل هرچیزی میتواند باشد) و یک فولدر به اسم models ایجاد کنید. ( دقت کنید که اسم این فولدر models باشد!) داخل این فولدر یک فایل ایجاد کنید. اینکه نام این فایل چی باشه بهتره که جوری نام گذاری کنید مرتبط با جداول دیتابیس باشه. من برای هر جدولم یک فایل جداگانه ایجاد کردم. در این مرحله ۲تا فایل درست کردم ( چون بنظرم اینجوری دیباگ کردن مدلها ساده تر میشه نسبت به حالتی که همه مدلها در یک فایل باشند) tracks.py & albums.py داخل فولدر models ساختم. ( کمی جلوتر init.py را توضیح دادم)
ساختار پروژه باید چیزی شبیه به عکس زیر باشه:
داخل db.py کدهای زیر را بنویسید:
در خط سوم یک آبجکت از sqlqlchemy رو به متغیر db ارتباط میدیم. نام این متغیر رو میتونید هرچیزی بذارید.
در ادامه ما میتونیم با استفاده از این آبجکت دیتبابیس رو به پروژه مون متصل کنیم و داخل app.py ازش استفاده کنیم.
فرض من اینه که دوتا جدول دارم به اسم Tracks و Albums. رابطه بین این دوتا جدول به این صورت هستش که هر موسیقی باید داخل یک آلبوم باشه و هر آلبوم می تونه چندتا موسیقی داشته باشه. پس رابطه این دوتا جدول بصورت یک به چند هستش. (One(albums) To Many(tracks
حالا باید جدول های دیتابیس مون رو با استفاده از پایتون تعریف کنیم. اینکه اصول کار با sqlqlchemy چی هستش، من کامل نمیدونم!!! فعلا در همین حد یادگرفتم. اما خیلی شبیه به Modelها در جنگو هست.
در خط اول یک instance از sqlalchemi رو به کدمون اضافه میکنیم. داخل این نمونه هرچیزی که برای استفاده از جداول نیاز داریم وجود داره. در واقع هر کلاسی که اینجا میسازیم به یک جدول با ستون هایی نگاشت میشود.
خب، SQLAlchemy می دونه که جدول Albums توسط کلاس AlbumModel استفاده میشه. پس ما میتونیم با تعریف یک کلید خارجی، یک آبجکت از AlbumModel بسازیم. ستون albumId_ مشخص کننده کلید خارجی هستش. با استفاده از db.relationship رابطه بین دو تا جدول رو مشخص کردم و یک آبجکت از AlbumModel به album_ نسبت دادم. چون آبجکت album_ از کلاس AlbumModel استفاده میکنه sqlalchemy متوجه میشه که در این جدول یک کلیدخارجی وجود داره که به AlbumModel اشاره میکنه، پس این آبجکت به نمونه ای از AlbumModel نگاشت میشه که کلید خارجی این جدول مشخص میکنه.
در جدول Albums هم یک آبجکت از TrackModel ایجاد کردم. و اینجوری این جدول به راحتی میتونه ردیف متناسبش رو در جدول Tracks رو ببینه :) البته به این معنی نیست که یک رابطه چند به چند ایجاد شده!!
در هر دو جدول یک آبجکت دارم که با تعریف back_populates به همدیگه متصل شده اند. اینجوری sqlalchemy متوجه میشه که این آبجکتها دو سر یک رابطه هستند و دیگر نیازی به تعریف کلید خارجی در جدول دوم نداریم. البته دقت کنید که این رابطه همچنان یک رابطه یک به چند هستش. قبول دارم کمی گیج کننده است ولی به مرور و با کد زدن بیشتر به مفهوم این مورد پی میبرید. و قطعا پیشنهاد میکنم که داکیومنت sqlalchemy و flask_sqlalchemy رو بخونید.
صرفا براساس تجربههای دیگران و اینکه در برخی منابع دیدم این نوع تعریف رابطه باعث بهبود عملکرد میشه و دسترسی ما به مدلها رو راحت تر میکنه، ترجیج دادم اینگونه رابطه رو تعریف کنم و از هر دو جدول قابل دسترسی باشه اما یک رابطه یک به چند باشه!
برای اینکه در ادامه پروژه راحت باشیم و نیاز نباشه که مدام مدلها را import کنیم از این فایل استفاده میکنیم. در ادامه هرجایی از پروژه اگر import models رو بنویسیم، هرتعداد مدلی که داخل فولدر models باشه import میشه بدون اینکه نیاز باشه دونه دونه انجام بدید.
در این مرحله چون مدلهای کمی دارم بظاهر این کار نیاز نیست اما در ادامه متوجه میشید که این فایل چقدر کمک میکنه.
الان نیاز هستش که دیتابیس رو به پروژه متصل کنیم.
اول از همه importها رو انجام بدید:
کانفیگ های زیر را هم به app اضافه کنید.
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///data.db" app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False db.init_app(app)
دو خط اول کانفیگ های مربوط به دیتابیس و SQLAlchemy هستند و در خط سوم sqlalchemy رو به app متصل کردم. ( db یک آبجکت از sqlalchemy است که در فایل db.py تعریف کردم.)
اینکه چه دیتایی وارد دیتابیس بشه و چه مواردی ممنوع هستد و .... و جلوگیری کنیم از ورود اطالاعات غیرتکرای و هم اینکه خطاها رو مدیریت کنیم تا برای کاربر قابل فهم باشند از marshmallow در فلسک استفاده میشه.
مارشمالو برای موارد زیر استفاده میشه و اینجا فقط به منظور data validation ازش استفاده کردم.
بزودی پست جداگانه ای برای این قسمت منتشر میکنم. فعلا منتظر باشید.
تا اینجا ما مدلهامون رو تعریف کردیم. ( درواقع همون جدولهای دیتابیس رو) به مرور این مدلها بزرگ میشن و نیاز به کوئری هم خواهیم داشت. فعلا در همین حد که با استفاده از sqlalchemy جدولهای دیتابیس رو ساختیم و به پروژه متصل کردیم کافیه. به مرور این پست کامل میشه.