کار با دتیابیس در Flask با استفاده از SQLAlchemy

یکی از راه های اتصال و کار با دیتابیس‌ها استفاده از ORM (object-relational mappe) ها هستش. یکی از این ابزارها برای زبان پایتون Alchemy است.

خب برای شروع و استفاده از Alchemy لازم است که موارد زیر نصب بشه: ( و مثل هر پروژه پایتونی دیگه بهتره که از virtualenv and requirements.txt استفاده کنید)

  • salalchemy
  • flask-alchemy (s an extension for Flask that adds support for SQLAlchemy to your application.)

ساختن مدل‌ها (جدول‌ها)

بعد از نصب موارد بالا (pip install -r requirements.txt) باید در فولدر پروژه تون (همون فولدری که app.py قرار داره) یک فایل بنامdb.py بسازید‌ (نام این فایل هرچیزی میتواند باشد) و یک فولدر به اسم models ایجاد کنید. ( دقت کنید که اسم این فولدر باید models باشد!) داخل این فولدر یک فایل ایجاد کنید. اینکه نام این فایل چی باشه بهتره که جوری نام گذاری کنید مرتبط با جداول دیتابیس باشه. من فایلی بنام models.py داخل فولدر models ساختم. (در این مرحله چون مدلها کوچک و روابط بین شون ساده هستند فعلا اینجوری نام گذاری کردم. شاید بعدا تغییر بدم) ساختار پروژه باید چیزی شبیه به عکس زیر باشه:

داخل db.py کدهای زیر را بنویسید:


خط دوم یک آبجکت از sqlqlchemy رو به متغیر db ارتباط میدیم. نام این متغیر رو می‌تونید هرچیزی بذارید.

در ادامه ما می‌تونیم با استفاده از این آبجکت دیتبابیس رو به پروژه مون متصل کنیم و داخل app.py ازش استفاده کنیم.

فرض من اینه که دوتا جدول دارم به اسم Tracks و Albums. رابطه بین این دوتا جدول به این صورت هستش که هر موسیقی باید داخل یک آلبوم باشه و هر آلبوم می تونه چندتا موسیقی داشته باشه. پس رابطه این دوتا جدول بصورت یک به چند هستش. (One(albums) To Many(tracks

حالا باید داخل فایل models.py جدول های دیتابیس مون رو با استفاده از پایتون تعریف کنیم. اینکه اصول کار با sqlqlchemy چی هستش هم من کامل نمی‌دونم. فعلا در همین حد یادگرفتم. اما خیلی شبیه به Modelها در پایتون هست.



در خط اول یک instance از sqlalchemi رو به کدمون اضافه می‌کنیم. داخل این نمونه هرچیزی که برای استفاده از جداول نیاز داریم وجود داره. در واقع هر کلاسی که اینجا می‌سازیم به یک جدول با ستون هایی نگاشت می‌شود.

با استفاده از __tablename__ نام جدول‌ها رو مشخص کردم.

هر attribute کلاس در واقع نام یک ستون در جدول رو مشخص می‌کنه. در هر دو جدول ستون id مشخص کننده کلید اصلی هستش.

ستون albumId_ مشخص کننده کلید خارجی هستش. با استفاده از db.relationship رابطه بین دو تا جدول رو مشخص کردم. این رابطه در واقع یک رابطه یک به چند دوطرفه هستش. با استفاده از album_ and track_ می‌تونیم به اطلاعات جدول دیگر دسترسی داشته باشیم. برای اینکه بهتر متوجه بشید داکیومنت sqlalchemi را بخونید.

اینکه چرا داخل جدول Albums کلید خارجی تعریف نشده به این خاطر است که رابطه بین دو جدول دوطرفه است و از اونجایی که در جدول Tracks رابطه رو با استفاده album_ به track_ مرتبط کردم، sqlalchemy متوجه میشه که این attributeها در واقع دو سر یک رابطه هستند. ( البته فراموش نکنید که رابطه بین دوتا جدول یک به چند است)

عبارت lazy=dynamic به این منظور است که این ستون جدول که درواقع از رابطه بین دونا جدول تشکیل میشه فقط هرزمانی که ما خواستیم تکمیل بشه. چون کوئری های join and search زمان زیادی صرف می‌کنند. با اینکار درواقع عملکرد و پایداری پروژه رو بالا می‌بریم.

ساختن init__.py__

برای اینکه در ادامه پروژه راحت باشیم و نیاز نباشه که مدام مدلها را import کنیم از این فایل استفاده میکنیم. در ادامه هرجایی از پروژه اگر import models ( منظور models.py است نه فولدر models) رو بنویسیم، هرتعداد مدلی که داخل فولدر models باشه import میشه بدون اینکه نیاز باشه دونه دونه انجام بدید.

در این مرحله چون مدلهای کمی دارم بظاهر این کار نیاز نیست اما در ادامه متوجه میشید که این فایل چقدر کمک میکنه.


کانفیگ کردن app.py

الان نیاز هستش که دیتابیس رو به پروژه متصل کنیم.

اول از همه importها رو انجام بدید:

  • import os
  • from db import db
  • import models

کانفیگ های زیر را هم به app اضافه کنید.

app.config[&quotSQLALCHEMY_DATABASE_URI&quot] = &quotsqlite:///data.db&quot
app.config[&quotSQLALCHEMY_TRACK_MODIFICATIONS&quot] = False
db.init_app(app)

دو خط اول کانفیگ های مربوط به دیتابیس و SQLAlchemy هستند و در خط سوم sqlalchemy رو به app متصل کردم. ( db یک آبجکت از sqlalchemy است که در فایل db.py تعریف کردم.)



بررسی کردن اطالاعات

اینکه چه دیتایی وارد دیتابیس بشه و چه مواردی ممنوع هستد و .... و جلوگیری کنیم از ورود اطالاعات غیرتکرای و هم اینکه خطاها رو مدیریت کنیم تا برای کاربر قابل فهم باشند از marshmallow در فلسک استفاده میشه.

مارشمالو برای موارد زیر استفاده می‌شه و اینجا فقط به منظور data validation ازش استفاده کردم.

  • Validate input data.
  • Deserialize input data to app-level objects.
  • Serialize app-level objects to primitive Python types. The serialized objects can then be rendered to standard formats such as JSON for use in an HTTP API.

بزودی پست جداگانه ای برای این قسمت منتشر می‌کنم. فعلا منتظر باشید.




تا اینجا ما مدل‌هامون رو تعریف کردیم. ( درواقع همون جدولهای دیتابیس رو) به مرور این مدلها بزرگ می‌شن و نیاز به کوئری هم خواهیم داشت. فعلا در همین حد که با استفاده از sqlalchemy جدولهای دیتابیس رو ساختیم و به پروژه متصل کردیم کافیه. به مرور این پست کامل میشه.