flask_cms استعمال مكتبة SQLAlchemy في مُفسّر لغة بايثون للتّعامل مع قاعدة بيانات التّطبيق


عبدالهادي الديوري

مُقدّمة

بعد إنشاء جدولي المقالات والمُستخدمين في قاعدة البيانات في الدّرس السّابق، حان الوقت للتّعامل مع البيانات وإدارتها باستعمال لغة بايثون عوضا عن لغة SQL؛ في هذا الدّرس سنتعرّف على كيفيّة الوصول إلى مُفسّر بايثون في مجلّد مشروعنا وكذلك كيفيّة إضافة البيانات وجلبها من قاعدة البيانات.

الوصول إلى مُفسّر بايثون داخل مُجلّد المشروع

سنقوم في هذا الدّرس بالتّعامل مع قاعدة البيانات باستعمال Flask-SQLAlchemy مُباشرة من مُفسّر بايثون، إن كنت على نظام Windows فهو في الغالب متواجد في قائمة ابدأ، أمّا إن كنت على لينكس أو OSX فادخل إلى الطّرفيّة Terminal واكتب python تأكّد فقط من أنّك في مُجلّد kalima قبل أن تقوم بالوصول إلى مُفسّر بايثون، وتأكّد كذلك بأنّك قد فعّلت البيئة الوهميّة.

إن لم تستطع الوصول إلى مُفسّر بايثون في مُجلّد kalima فيُمكنك تنفيذ الأمر chdir من وحدة os لتغيير المُجلّد الحالي إلى مسار مُجلّد kalima:

>>> import os

>>> os.chdir('path/to/kalima')

مع تغيير path/to/kalima إلى مسار مُجلّد kalima في حاسوبك.

مُلاحظة: الشّيفرة التّي سأقوم بتنفيذها ستُسبق بعلامة >>> أمّا المُخرج/النّتيجة فلن يُسبق بشيء.

مثال:

>>> site = 'Hsoub Academy'
>>> site
'Hsoub Academy'

بما أنّنا في مُفسّر بايثون نستطيع الوصول إلى قيمة المُتغيّر دون طباعتها، فقط اكتب اسم المُتغيّر ثم اضغط مفتاح ENTER.

سنستعمل كلّا من db والصّنفين اللذ]ن يُشكلان كلّا من جدول المقالات والمُستخدمين للتّعامل مع البيانات فيها، وللوصول إلى كلّ من الكائن db والصّنفين Post و User يجب عليك أن تقوم باستيرادها:

>>> from project import db
>>> from project.models import Post, User

إن حصلت على خطأ كما يلي:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named project

فهذا يعني بأنّك لست في مجلّد kalima لذا تأكّد من أنّك اتّبعت الإرشادات السّابقة على نحو صحيح.

إدخال البيانات إلى قاعدة البيانات

الآن، بعد استيراد كلّ من الكائن db والصّنفين Post وUser نستطيع القيام بأول عمليّة، ألا وهي عمليّة الإضافة، وسنُضيف أولا مُستخدما باسم khalid وبعدها سنُضيف مقالا له بعنوان Post 1.

إضافة المُستخدم

لإضافة مُستخدم سنُنشئ أولا كائنا من الصّنف User مع المعاملات التّي حدّدناها سابقا في دالّة init الخاصّة بالصّنف، ما يعني بأنّنا سنُنشئ مُستخدما كما يلي:

user = User('khalid', 'email@example.com', 'password')

وهنا يكون التّرتيب مُهمّا ومُطابقا لترتيب المُعاملات في الدّالة __init__، ويُمكنك كذلك تسميّة كلّ معامل وتغيير التّرتيب إن لم تتذكّر سوى أسماء المعاملات كما يلي:

user = User(password='password', email='email@example.com',name='khalid')

كما تُلاحظ عندما تذكر اسم كلّ معامل، فالتّرتيب غير مهم خلافا للمثال الأول.

بعد إنشاء الكائن من صنف المُستخدم بالبيانات التّي نُريدها، يُمكننا الوصول إلى كل قيمة أو تغييرها ببساطة:

>>> user = User('khalid', 'email@example.com', 'password')
>>> user.name
'khalid'
>>> user.email
'email@example.com'
>>> user.password
'password'

>>> user.email = 'khalid@example.com'
>>> user.email
'khalid@example.com'

>>> user
<username: khalid | email: khalid@example.com >

كما تُلاحظ، يُمكننا الوصول إلى كل قيمة من القيم التّي حدّدناها سابقا وكذا تعديلها بإسناد قيمة جديدة بكل بساطة.

لاحظ كذلك مُخرجات آخر أمر، يُمكنك أن ترى بأنّ طريقة التّنسيق هذه هي نفسها ما قد حدّدناه سابقا في الدّالة __repr__ بالصّنف User، وإليك تذكيرا سريعا:

def __repr__(self):
    return '<username: {} | email: {} >'.format(self.name, self.email)

وأنبّه إلى أنّنا لم نغيّر أي شيء بعد في قاعدة البيانات، وإنشاء الكائن ليس سوى تمهيد لإضافته إلى جلسة تتواجد في الكائن db ثمّ تأكيد التّغييرات لإضافة المُستخدم إلى قاعدة البيانات حقيقة، ولإضافة الكائن user الذي أنشأناها قبل قليل إلى الجلسة نقوم بما يلي:

>>> db.session.add(user)

والجلسة هنا عبارة عن مكان لإضافة البيانات لوضعها بعد ذلك في قاعدة البيانات، وعند إضافة كل كائن إلى الجلسة لا يُضاف إلى قاعدة البيانات حقيقة إلى أن تنفّذ الأمر db.session.commit.
لذا لإضافة المُستخدم خالد إلى قاعدة البيانات PostgreSQL فسننفّذ الأمر التّالي:

>>> db.session.commit()

بعد تنفيذ الأمر والعودة إلى أداة psql لعرض جميع البيانات في جدول المُستخدمين فستلاحظ بأنّ المُستخدم الذي أضفناه موجود بالفعل:

kalima=# select * from users;


 id |  name  |       email        | password |        created_date        
----+--------+--------------------+----------+----------------------------
  1 | khalid | khalid@example.com | password | 2017-04-08 18:48:05.316805
(1 row)

لاحظ بأنّ العمود id أخذ القيمة 1 رغم أنّنا لم نُحدّدها، ولو أضفنا مُستخدما آخر الآن لكان رقم مُعرّفه 2 ولو حذفت مثلا المُستخدم الذي يحمل رقم المعرّف 1 وأضفت مُستخدما آخر، فرقم مُعرّف هذا المُستخدم لن يأخذ مكان المُستخدم الأول بل سيأخذ رقما جديدا مُخالفا للأرقام السّابقة؛ ولاحظ كذلك بأنّ تاريخ الإضافة قد أضيف دون أن نقوم بتحديده يدويا.

إضافة المقال

بعد أن قُمنا بإضافة المُستخدم، حان الوقت لإضافة مقال خاص به، بالطّبع في التّطبيق المُستخدِم هو من سيُضيف مقالاته، وبعد تسجيله الدّخول، سنستطيع إضافة المقال ووضع قيمة مفتاح مُعرّفه كقيمة للمُعامل author_id، وسنقوم في هذا الجزء بإعطاء مثال لكيفيّة إضافة مقال وإسناد كاتب له، وفي الجزء التّالي سوف نضيف المزيد من المقالات والمُستخدمين لشرح كيفيّة الوصول إلى بيانات كل مُستخدم بما فيها مقالاته، وكذا كاتب كلّ مقال.

لإضافة المقال ذي العنوان Post 1 نقوم بنفس الشّيء، أولا نُنشئ كائنا من الصّنف Post ثمّ نُسند له القيم التّي حدّدناها سابقا في الدّالة __init__ الخّاصّة بالصّنف، لكن هذه المرّة نقوم بإضافة مُعامل آخر، وهو عبارة عن قيمة رقم مُعرّف المُستخدم الذي أضاف المقال، وبما أنّنا نمتلك مُستخدما رقم مُعرّفه 1 فهذا يعني بأنّنا نستطيع أن نُسند له هذا المقال بصفته كاتبا له.

>>> post = Post('Post 1', 'post 1 content', author_id=1)
>>> post
<title Post 1 | post 1 content >

>>> db.session.add(post)
>>> db.session.commit()

>>> post.author
<username: khalid | email: khalid@example.com >
>>> post.author.name
u'khalid'
>>> post.author.email
u'khalid@example.com'
>>> post.author.password
u'password'

كما تُلاحظ، يُمكنك تحديد أسماء معاملات إن أردت، وترك أسماء أخرى على شرط أن تكون القيم مُرتّبة، فقد ذكرت اسم المُعامل author_id فقط لكي تفهم القيمة الثّالثة، وسيتوجّب عليك ذكر الاسم إن كان لك العديد من المفاتيح الأجنبيّة (أرقام مُعرّف تُشير إلى جداول كثيرة) لأنّها ستكون كلّها عبارة عن أرقام لا معنى لها لمن يقرأ الشّيفرة، ويجب عليك أن تتذكّر ترتيبها باستمرار، لذا من المُفضّل تجنّب هذا بذكر اسم كلّ معامل.

لاحظ كذلك عندما نستدعي الكائن، فإنّ الدّالة __repr__ تستبدل كلّا من المنطقتين بالعنوان والمحتوى كما هو مُتوقّع.
بعد إضافة المقال إلى الجلسة ثمّ تأكيد التّغييرات وكتابتها إلى قاعدة البيانات، أصبح بإمكاننا الآن الوصول إلى كاتب المقال عن طريق post.author والمُخرج عبارة عن كائن يحمل بيانات المُستخدم الذي أدخل البيانات كما لو أنّك حصلت عليه من قاعدة البيانات، إذ تستطيع الوصول إلى قيمة أي عمود في جدول المُستخدمين والنّتيجة تكون عبارة عن سلسلة نصيّة مسبوقة بحرف u للإشارة إلى أنّها عبارة عن Unicode وبالطّبع يُمكنك التّعامل معها كما تتعامل مع سلسلة نصيّة عاديّة.

بعد الوصول إلى المُستخدم كاتب المقال، يُمكنك الحصول على مقالاته الأخرى كذلك:

>>> post.author.posts.all()
[<title Post 1 | post 1 content >]

المُخرج عبارة عن قائمة من المقالات يُمكنك الدّوران حولها باستخدام حلقة for ولأنّنا لا نمتلك سوى مقال واحد حاليّا، سنقوم بالوصول إليه مُباشرة برقم العنصر في القائمة:

>>> post.author.posts[0]
<title Post 1 | post 1 content >

>>> post.author.posts[0].title
u'Post 1'

>>> post.author.posts[0].content
u'post 1 content'

>>> post.author.posts[0].author
<username: khalid | email: khalid@example.com >

لاحظ أنّنا استطعنا الوصول إلى كاتب المقال مُجدّدا في آخر سطر، يُمكنك الاستمرار إلى ما لانهاية، المقال –> كاتبُه –> مقال كَتَبه –> كاتبُه –> مقال كَتَبه –> كاتبُه وهكذا…
ما يعني بأنّ السّطر التّالي مُمكن:

>>> post.author.posts[0].author.posts[0].author.posts[0].author.posts[0].author.posts[0].author.name
u'khalid'

بالطّبع، لا فائدة من استعمال SQLAlchemy بهذه الطّريقة، إنّما يجب عليك أن تفهم كيف يعمل، وبأنّ مثل هذه الأمور مُمكنة فربّما تُفيدك في تفادي بعض الأخطاء البرمجيّة.

خاتمة

تعرّفنا في هذا الدّرس على كيفيّة استعمال مُفسّر لغة بايثون للتّعامل مع قاعدة البيانات الخاصّة بنا، وتمكّنّا من إضافة سجلّ إلى جدول المُستخدمين وسجلّ آخر إلى جدول المقالات. في الدّرس القادم، سنطّلع على كيفيّة إنشاء العديد من السّجلات لنتمكّن من العمل معها في بقيّة الدّروس الخاصّة بالتّعامل مع قاعدة البيانات باستعمال مكتبة SQLAlchemy لتتمكّن من تطوير تطبيقات ويب أفضل وأكثر تعقيدا باستعمال إطار العمل Flask.





تفاعل الأعضاء


لا توجد أيّة تعليقات بعد



يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن