Skip to content

9. استخدام SGBD MySQL

9.1. تثبيت الوحدة النمطية MySQLdb

سنقوم بكتابة نصوص برمجية تستخدم قاعدة بيانات MySQL:

وظائف Python الخاصة بإدارة قاعدة البيانات MySQL مدمجة في وحدة نمطية MySQLdb غير مضمنة في التوزيع الأولي لـ Python. لذا، يجب تنزيل الوحدة النمطية وتثبيتها. وإليك إحدى طرق القيام بذلك:

  • في قائمة البرامج، اختر [1]، وهو مدير حزم Python. ستظهر عندئذٍ نافذة الأوامر [2].

ابحث عن الكلمة الرئيسية mysql في الحزم:


C:\Documents and Settings\st>pypm search mysql
Get: [pypm-be.activestate.com] :repository-index:
Get: [pypm-free.activestate.com] :repository-index:
autosync: synced 2 repositories
  chartio                    Setup wizard and connection client for connecting
  chartio-setup              Setup wizard and connection client for connecting
  cns.recipe.zmysqlda        Recipe for installing ZMySQLDA
  collective.recipe.zmysqlda Recipe for installing ZMySQLDA
  django-mysql-manager       DESCRIPTION_DESCRIPTION_DESCRIPTION
  jaraco.mysql               MySQLDB-compatible MySQL wrapper by Jason R. Coomb
  lovely.testlayers          mysql, postgres nginx, memcached cassandra test la
  mtstat-mysql               MySQL Plugins for mtstat
  mysql-autodoc              Generate HTML documentation from a mysql database
  mysql-python               Python interface to MySQL
  mysqldbda                  MySQL Database adapter
  products.zmysqlda          MySQL Zope2 adapter.
  pymysql                    Pure Python MySQL Driver
  pymysql-sa                 PyMySQL dialect for SQLAlchemy.
  pymysql3                   Pure Python MySQL Driver
  sa-mysql-dt                Alternative implementation of DateTime column for
  schemaobject               Iterate over a MySQL database schema as a Python o
  schemasync                 A MySQL Schema Synchronization Utility
  simplestore                A datastore layer built on top of MySQL in Python.
  sqlbean                    A auto maping ORM for MYSQL and can bind with memc
  sqlwitch                   sqlwitch offers idiomatic SQL generation on top of
  tiddlywebplugins.mysql     MySQL-based store for tiddlyweb
  tiddlywebplugins.mysql2    MySQL-based store for tiddlyweb
zest.recipe.mysql          A Buildout recipe to setup a MySQL database.

تم سرد جميع الوحدات التي يحتوي اسمها أو وصفها على الكلمة المفتاحية mysql. الوحدة التي تهمنا هي [mysql-python]، في السطر 14. نقوم بتثبيتها:


C:\Documents and Settings\st>pypm install mysql-python
The following packages will be installed into "%APPDATA%\Python" (2.7):
 mysql-python-1.2.3
Hit: [pypm-free.activestate.com] mysql-python 1.2.3
Installing mysql-python-1.2.3

C:\Documents and Settings\st>echo %APPDATA%
C:\Documents and Settings\st\Application Data
  • السطر 5: تم تثبيت الحزمة mysql-python-1.2.3 في المجلد "%APPDATA%\Python"، حيث APPDATA هو المجلد المحدد في السطر 8.

قد تفشل هذه العملية في الحالات التالية:

  • كان مترجم Python المستخدم إصدارًا 64 بت؛
  • إذا كان المسار %APPDATA% يحتوي على أحرف ذات علامات تشكيل.

9.2. تثبيت MySQL

هناك طرق متنوعة لتثبيت SGBD MySQL. هنا استخدمنا WampServer، وهو حزمة تضم عدة برامج:

  • خادم ويب Apache. سنستخدمه لكتابة نصوص برمجية ويب بلغة Python؛
  • برنامج SGBD و MySQL؛
  • لغة البرمجة النصية PHP؛
  • أداة لإدارة SGBD MySQL مكتوبة بلغة PHP: phpMyAdmin.

يمكن تنزيل WampServer (يونيو 2011) من العنوان التالي:

http://www.wampserver.com/download.php
  • في [1]، يتم تنزيل الإصدار المناسب من WampServer؛
  • في حالة [2]، بمجرد تثبيته، يتم تشغيله. سيؤدي ذلك إلى تشغيل خادم الويب Apache وبرنامج SGBD وMySQL؛
  • في [3]، بمجرد تشغيله، يمكن إدارة WampServer من خلال أيقونة [3] الموجودة في أسفل يمين شريط المهام؛
  • في [4]، يتم تشغيل أداة إدارة MySQL.

يتم إنشاء قاعدة بيانات [dbpersonnes]:

Image

يتم إنشاء مستخدم [admpersonnes] بكلمة مرور [nobody]:

  • في [1]، اسم المستخدم؛
  • إلى [2]، الجهاز الخاص بـ SGBD الذي تم منحه حقوقًا عليه؛
  • في [3]، كلمة مروره [nobody
  • في [4]، نفس الشيء؛
  • في [5]، لا تُمنح أي صلاحيات لهذا المستخدم؛
  • في [6]، يتم إنشاؤه.
  • في [7]، نعود إلى الصفحة الرئيسية لـ phpMyAdmin؛
  • في [8]، نستخدم الرابط [Privileges] الموجود في هذه الصفحة للانتقال لتعديل ربطات المستخدم [admpersonnes] و[9].
  • في [10]، نحدد أننا نريد منح المستخدم [admpersonnes] حقوقًا على قاعدة البيانات [dbpersonnes
  • في [11]، يتم تأكيد الاختيار.
  • مع الرابط [12] [Tout cocher]، يُمنح المستخدم [admpersonnes] جميع الحقوق على قاعدة البيانات [dbpersonnes] [13]؛
  • ثم يتم التحقق من صحة العملية في [14].

والآن لدينا:

  • قاعدة بيانات MySQL و [dbpersonnes
  • مستخدم [admpersonnes / nobody] يتمتع بجميع الصلاحيات على قاعدة البيانات هذه.

سنقوم بكتابة نصوص برمجية بلغة Python لاستغلال قاعدة البيانات.

9.3. الاتصال بقاعدة البيانات MySQL - 1


البرنامج (mysqldb_01)


# استيراد الوحدة النمطية MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb

# الاتصال بقاعدة بيانات MySQL
....

ملاحظات:

  • الأسطر 2-4: يجب أن تستورد البرامج النصية التي تحتوي على عمليات مع SGBD و MySQL الوحدة النمطية MySQLdb. نتذكر أننا قمنا بتثبيت هذه الوحدة النمطية في المجلد [%APPDATA%\Python]. يتم استكشاف المجلد [%APPDATA%\Python] تلقائيًا عندما يطلب كود Python وحدة نمطية. في الواقع، يتم استكشاف جميع المجلدات المُعلنة في sys.path. فيما يلي مثال يعرض هذه المجلدات:

# -*- coding=utf-8 -*-

import sys

# عرض المجلدات من sys.path
for dossier in sys.path:
    print dossier

ويكون العرض على الشاشة كما يلي:

D:\data\istia-1112\python\tutoriel
C:\Windows\system32\python27.zip
D:\Programs\ActivePython\Python2.7.2\DLLs
D:\Programs\ActivePython\Python2.7.2\lib
D:\Programs\ActivePython\Python2.7.2\lib\plat-win
D:\Programs\ActivePython\Python2.7.2\lib\lib-tk
D:\Programs\ActivePython\Python2.7.2
C:\Users\Serge TahÚ\AppData\Roaming\Python\Python27\site-packages
D:\Programs\ActivePython\Python2.7.2\lib\site-packages
D:\Programs\ActivePython\Python2.7.2\lib\site-packages\win32
D:\Programs\ActivePython\Python2.7.2\lib\site-packages\win32\lib
D:\Programs\ActivePython\Python2.7.2\lib\site-packages\Pythonwin
D:\Programs\ActivePython\Python2.7.2\lib\site-packages\setuptools-0.6c11-py2.7.egg-info

السطر 8، المجلد [site-packages] حيث تم تثبيت MySQLdb في البداية. نقوم بنقل المجلد [site-packages]، وهو المجلد الذي تقوم فيه الأداة المساعدة pypm بتثبيت وحدات Python. لإضافة مجلد جديد سيقوم Python بالبحث فيه عن الوحدات، نضيفه إلى القائمة sys.path:


# استيراد الوحدة النمطية MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb

# تسجيل الدخول إلى قاعدة بيانات MySQL
....

في السطر 3، نضيف المجلد الذي تم نقل الوحدة النمطية MySQLdb إليه.

فيما يلي الكود الكامل للمثال:


# استيراد الوحدة النمطية MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb

# الاتصال بقاعدة بيانات MySQL
# هوية المستخدم هي (admpersonnes، nobody)
user="admpersonnes"
pwd="nobody"
host="localhost"
connexion=None
try:
    print "connexion..."
    # تسجيل الدخول
    connexion=MySQLdb.connect(host=host,user=user,passwd=pwd)
    # المتابعة
    print "Connexion a MySQL reussie sous l'identite host={0},user={1},passwd={2}".format(host,user,pwd)
except MySQLdb.OperationalError,message:
    print "Erreur : {0}".format(message)
finally:
    try:
        connexion.close()
    except:
        pass

  • الأسطر 8-11: سيقوم البرنامج النصي (في السطر 15) بتوصيل المستخدم [admpersonnes / nobody] بـ SGBD و MySQL على الجهاز [localhost]. ولا يتم توصيله بقاعدة بيانات محددة؛
  • الأسطر 12-24: قد يفشل الاتصال. ولذلك يتم إجراؤه ضمن بنية try / except / finally؛
  • السطر 15: تقبل الطريقة connect في الوحدة النمطية MySQLdb معلمات مختلفة مسماة:
    • user: المستخدم المالك للاتصال [admpersonnes
    • pwd: كلمة مرور المستخدم [nobody
    • host: جهاز نظام إدارة قواعد البيانات MySQL [localhost
    • db: قاعدة البيانات التي يتم الاتصال بها. اختياري.
  • السطر 18: في حالة حدوث استثناء، يكون من النوع [ MySQLdb.OperationalError] وستوجد رسالة الخطأ المرتبطة به في المتغير [message
  • الأسطر 20-23: في الجملة [finally]، يتم إغلاق الاتصال. في حالة حدوث استثناء، يتم اعتراضه (السطر 23) ولكن لا يتم اتخاذ أي إجراء حياله (السطر 24).

النتائج

connexion...
Connexion a MySQL reussie sous l'identite host=localhost,user=admpersonnes,passwd=nobody

9.4. الاتصال بقاعدة بيانات MySQL - 2


البرنامج (mysqldb_02)


# استيراد الوحدة النمطية MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb

# ---------------------------------------------------------------------------------
def testeConnexion(hote,login,pwd):
    # تسجيل الدخول ثم تسجيل الخروج (login,pwd) من قاعدة بيانات mysql على الخادم المضيف
    # إطلاق استثناء MySQLdb.operationalError
    # تسجيل الدخول
    connexion=MySQLdb.connect(host=hote,user=login,passwd=pwd)
    print "Connexion a MySQL reussie sous l'identite (%s,%s,%s)" % (hote,login,passwd)
    # يتم إغلاق الاتصال
    connexion.close()
    print "Fermeture connexion MySQL reussie\n"
 

# ---------------------------------------------- main
# تسجيل الدخول إلى قاعدة البيانات MySQL
# هوية المستخدم
user="admpersonnes"
passwd="nobody"
host="localhost"
# اختبار الاتصال
try:
    testeConnexion(host,user,passwd)
except MySQLdb.OperationalError,message:
    print message
# باستخدام مستخدم غير موجود
try:
    testeConnexion(host,"xx","xx")
except MySQLdb.OperationalError,message:
    print message

ملاحظات:

  • الأسطر 7-15: دالة تحاول توصيل مستخدم بقاعدة بيانات SGBD ثم فصله عنها. تعرض النتيجة؛
  • الأسطر 18-34: البرنامج الرئيسي – يستدعي الأسلوب testeConnexion مرتين ويعرض أي استثناءات قد تحدث.

النتائج

1
2
3
4
Connexion a MySQL reussie sous l'identite (localhost,admpersonnes,nobody)
Fermeture connexion MySQL reussie

Echec de la connexion a MySQL : (1045, "Access denied for user 'xx'@'localhost'(using password: YES)")

9.5. إنشاء جدول MySQL

الآن بعد أن تعلمنا كيفية إنشاء اتصال باستخدام SGBD MySQL، سنبدأ في إصدار الأوامر SQL عبر هذا الاتصال. للقيام بذلك، سنقوم بالاتصال بقاعدة البيانات التي تم إنشاؤها ([dbpersonnes]) واستخدام هذا الاتصال لإنشاء جدول داخل قاعدة البيانات.


البرنامج (mysqldb_03)


# استيراد الوحدة النمطية MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb

# ---------------------------------------------------------------------------------
def executeSQL(connexion,update):
    # تنفيذ طلب تحديث على الاتصال
    # طلب مؤشر
    curseur=connexion.cursor()
    # تنفيذ استعلام SQL على الاتصال
    try:
        curseur.execute(update)
        connexion.commit()
    except Exception, erreur:
        connexion.rollback()
        raise
    finally:
        curseur.close()

# ---------------------------------------------- main
# الاتصال بقاعدة البيانات MySQL
# هوية المستخدم
ID="admpersonnes"
PWD="nobody"
# الجهاز المضيف لنظام إدارة قواعد البيانات
HOTE="localhost"
# هوية قاعدة البيانات
BASE="dbpersonnes"
# الاتصال
try:
    connexion=MySQLdb.connect(host=HOTE,user=ID,passwd=PWD,db=BASE)
except MySQLdb.OperationalError,message:
    print message
    sys.exit()

# حذف جدول الأشخاص إن وجد
# وإذا لم تكن موجودة، فسيحدث خطأ
# يتم تجاهلها
requete="drop table personnes"
try:
    executeSQL(connexion,requete)
except:
    pass
# إنشاء جدول الأشخاص
requete="create table personnes (prenom varchar(30) NOT NULL, nom varchar(30) NOT NULL, age integer NOT NULL, primary key(nom,prenom))"
try:
    executeSQL(connexion,requete)
except MySQLdb.OperationalError,message:
    print message
    sys.exit()
# يتم قطع الاتصال والخروج
try:
    connexion.close()
except MySQLdb.OperationalError,message:
    print message
sys.exit()

ملاحظات:

  • السطر 7: تقوم الدالة executeSQL بتنفيذ استعلام SQL على اتصال مفتوح؛
  • السطر 10: تُجرى عمليات SQL على الاتصال من خلال كائن خاص يُسمى المؤشر؛
  • السطر 10: الحصول على مؤشر؛
  • السطر 13: تنفيذ الاستعلام SQL؛
  • السطر 14: يتم التحقق من صحة المعاملة الحالية؛
  • السطر 15: في حالة حدوث استثناء، يتم استرداد رسالة الخطأ في المتغير «erreur»؛
  • السطر 16: يتم إلغاء المعاملة الحالية؛
  • السطر 17: إعادة إطلاق الاستثناء؛
  • السطر 19: سواء حدث خطأ أم لا، يتم إغلاق المؤشر. وهذا يحرر الموارد المرتبطة به.

النتائج

create table personnes (prenom varchar(30) NOT NULL, nom varchar(30) NOT NULL, age integer NOT NULL, primary key(nom,prenom)) : requete reussie

التحقق باستخدام phpMyAdmin:

  • تحتوي قاعدة البيانات [dbpersonnes] [1] على جدول [personnes] [2] الذي له البنية [3] والمفتاح الأساسي [4].

9.6. ملء الجدول [personnes]

بعد أن أنشأنا سابقًا الجدول [personnes]، سنقوم الآن بملئه.


البرنامج (mysqldb_04)


# استيراد الوحدة النمطية MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb
# وحدات أخرى
import re

# ---------------------------------------------------------------------------------
def executerCommandes(HOTE,ID,PWD,BASE,SQL,suivi=False,arret=True):
    # استخدام الاتصال (HOTE، ID، PWD، BASE)
    # يُنفذ الأوامر SQL الموجودة في الملف النصي SQL عبر هذا الاتصال
    # هذا الملف هو ملف أوامر SQL يتم تنفيذها بمعدل أمر واحد في كل سطر
    # إذا كانت القيمة «متابعة» = «صحيح»، فإن كل عملية تنفيذ لأمر من أوامر SQL تُعرض مع إشارة إلى نجاحها أو فشلها
    # إذا كانت arret=True، تتوقف الدالة عند أول خطأ تصادفه، وإلا فإنها تنفذ جميع أوامر SQL
    # تُرجع الدالة قائمة (عدد الأخطاء، الخطأ 1، الخطأ 2، ...)

    # يتم التحقق من وجود الملف SQL
    data=None
    try:
        data=open(SQL,"r")
    except:
        return [1,"Le fichier %s n'existe pas" % (SQL)]

    # الاتصال
    try:
        connexion=MySQLdb.connect(host=HOTE,user=ID,passwd=PWD,db=BASE)
    except MySQLdb.OperationalError,erreur:
        return [1,"Erreur lors de la connexion a MySQL sous l'identite (%s,%s,%s,%s) : %s" % (HOTE, ID, PWD, BASE, erreur)]
    
    # يتم طلب مؤشر
    curseur=connexion.cursor()
    # تنفيذ الاستعلامات SQL الموجودة في الملف SQL
    # يتم وضعها في مصفوفة
    requetes=data.readlines()
    # يتم تنفيذها واحدة تلو الأخرى - في البداية لم تحدث أخطاء
    erreurs=[0]
    for i in range(len(requetes)):
        # يتم حفظ الاستعلام الحالي
        requete=requetes[i]
        # هل الاستعلام فارغ؟ إذا كان الجواب نعم، ننتقل إلى الاستعلام التالي
        if re.match(r"^\s*$",requete):
            continue
        # تنفيذ الاستعلام i
        erreur=""
        try:
            curseur.execute(requete)
        except Exception, erreur:
            pass
        #هل حدث خطأ؟
        if erreur:
            # خطأ آخر
            erreurs[0]+=1
            # رسالة خطأ
            msg="%s : Erreur (%s)" % (requete,erreur)
            erreurs.append(msg)
            # هل يتم عرض الشاشة أم لا؟
            if suivi:
                print msg
            # هل نتوقف؟
            if arret:
                return erreurs
        else:
            if suivi: 
                print "%s : Execution reussie" % (requete)
    # إغلاق الاتصال وتحرير الموارد
    curseur.close()
    connexion.commit()
    # يتم قطع الاتصال
    try:
        connexion.close()
    except MySQLdb.OperationalError,erreur:
        # خطأ آخر
        erreurs[0]+=1
        # رسالة خطأ
        msg="%s : Erreur (%s)" % (requete,erreur)
        erreurs.append(msg)

    # العودة
    return erreurs


# ---------------------------------------------- main
# الاتصال بقاعدة البيانات MySQL
# هوية المستخدم
ID="admpersonnes"
PWD="nobody"
# الجهاز المضيف لنظام إدارة قواعد البيانات
HOTE="localhost"
# هوية قاعدة البيانات
BASE="dbpersonnes"
# معرف ملف الأوامر النصية SQL المطلوب تنفيذه
TEXTE="sql.txt";

# إنشاء الجدول وتعبئته
erreurs=executerCommandes(HOTE,ID,PWD,BASE,TEXTE,True,False)
#عرض عدد الأخطاء
print "il y a eu %s erreur(s)" % (erreurs[0])
for i in range(1,len(erreurs)):
    print erreurs[i]


النتائج

الملف sql.txt:

1
2
3
4
5
6
7
8
9
drop table personnes
create table personnes (prenom varchar(30) not null, nom varchar(30) not null, age integer not null, primary key (nom,prenom))
insert into personnes values('Paul','Langevin',48)
insert into personnes values ('Sylvie','Lefur',70)
xx

insert into personnes values ('Pierre','Nicazou',35)
insert into personnes values ('Geraldine','Colou',26)
insert into personnes values ('Paulette','Girond',56)

تم إدراج خطأ متعمد في السطر 5.

نتائج العرض على الشاشة:

drop table personnes : Execution reussie
create table personnes (prenom varchar(30) not null, nom varchar(30) not null, age integer not null, primary key (nom,prenom)) : Execution reussie
insert into personnes values('Paul','Langevin',48) : Execution reussie
insert into personnes values ('Sylvie','Lefur',70) : Execution reussie
xx : Erreur ((1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xx' at
 line 1"))
insert into personnes values ('Pierre','Nicazou',35) : Execution reussie
insert into personnes values ('Geraldine','Colou',26) : Execution reussie
insert into personnes values ('Paulette','Girond',56) : Execution reussie
il y a eu 1 erreur(s)
xx : Erreur ((1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xx' at line 1"))

التحقق باستخدام phpMyAdmin:

Image

  • في [1]، يتيح الرابط [Afficher] الحصول على محتوى الجدول [personnes] [2].

9.7. تنفيذ أي استعلامات SQL

يتيح البرنامج النصي التالي تنفيذ ملف أوامر SQL وعرض نتيجة كل منها:

  • نتيجة الأمر SELECT إذا كان الأمر هو SELECT؛
  • عدد الأسطر التي تم تعديلها إذا كان الأمر هو INSERT أو UPDATE أو DELETE.

البرنامج (mysqldb_05)


# استيراد الوحدة النمطية MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb
# وحدات أخرى
import re

def cutNewLineChar(ligne):
    # حذف علامة نهاية السطر من [ligne] إن وجدت
    l=len(ligne)
    while(ligne[l-1]=="\n" or ligne[l-1]=="\r"):
        l-=1
    return(ligne[0:l])

# ---------------------------------------------------------------------------------
def afficherInfos(curseur):
    # عرض نتيجة استعلام SQL
    # هل كان هذا استعلام SELECT؟
    if curseur.description:
        # يوجد وصف — لذا فهو أمر SELECT
        # description[i] هو وصف العمود رقم i في أمر select
        # descriptionQZXW2HTMLBW2ldZQXQZXW2HTMLBWzBdZQX هو اسم العمود رقم i في قائمة الاختيار
        # يتم عرض أسماء الحقول
        titre=""
        for i in range(len(curseur.description)):
            titre+=curseur.description[i][0]+","
        # يتم عرض قائمة الحقول بدون الفاصلة الختامية
        print titre[0:len(titre)-1]
        # خط فاصل
        print "-"*(len(titre)-1)
        # السطر الحالي في قائمة الاختيار
        ligne=curseur.fetchone()
        while ligne:
            print ligne
            # السطر التالي في قائمة الاختيار
            ligne=curseur.fetchone()
    else:
        # لا توجد حقول - لم يكن هذا قائمة
        print "%s lignes(s) a (ont) ete modifiee(s)" % (curseur.rowcount)


# ---------------------------------------------------------------------------------
def executerCommandes(HOTE,ID,PWD,BASE,SQL,suivi=False,arret=True):
    # يستخدم الاتصال (HOTE،ID،PWD،BASE)
    # يُنفذ عبر هذا الاتصال الأوامر SQL الموجودة في الملف النصي SQL
    # هذا الملف هو ملف أوامر SQL يتم تنفيذها بمعدل أمر واحد في كل سطر
    # إذا كانت القيمة «متابعة» تساوي 1، فإن كل عملية تنفيذ لأمر من أوامر SQL تُعرض مع إشارة إلى نجاحها أو فشلها
    # إذا كانت القيمة «arret» تساوي 1، تتوقف الدالة عند أول خطأ تصادفه، وإلا فإنها تنفذ جميع أوامر SQL
    # تُرجع الدالة مصفوفة (عدد الأخطاء، الخطأ 1، الخطأ 2، ...)

    # يتم التحقق من وجود الملف SQL
    data=None
    try:
        data=open(SQL,"r")
    except:
        return [1,"Le fichier %s n'existe pas" % (SQL)]

    # تسجيل الدخول
    try:
        connexion=MySQLdb.connect(host=HOTE,user=ID,passwd=PWD,db=BASE)
    except MySQLdb.OperationalError,erreur:
        return [1,"Erreur lors de la connexion a MySQL sous l'identite (%s,%s,%s,%s) : %s" % (HOTE, ID, PWD, BASE, erreur)]
    
    # يتم طلب مؤشر
    curseur=connexion.cursor()
    # تنفيذ الاستعلامات SQL الموجودة في الملف SQL
    # يتم وضعها في مصفوفة
    requetes=data.readlines()
    # يتم تنفيذها واحدة تلو الأخرى - في البداية لم تحدث أخطاء
    erreurs=[0]
    for i in range(len(requetes)):
        # يتم حفظ الاستعلام الحالي
        requete=requetes[i]
        # هل الاستعلام فارغ؟ إذا كان الجواب نعم، ننتقل إلى الاستعلام التالي
        if re.match(r"^\s*$",requete):
            continue
        # تنفيذ الاستعلام i
        erreur=""
        try:
            curseur.execute(requete)
        except Exception, erreur:
            pass
        #هل حدث خطأ؟
        if erreur:
            # خطأ آخر
            erreurs[0]+=1
            # رسالة خطأ
            msg="%s : Erreur (%s)" % (requete,erreur)
            erreurs.append(msg)
            # هل يتم عرض الشاشة أم لا؟
            if suivi:
                print msg
            # هل نتوقف؟
            if arret:
                return erreurs
        else:
            if suivi: 
                print "%s : Execution reussie" % (requete)
                # معلومات حول نتيجة الاستعلام الذي تم تنفيذه
                afficherInfos(curseur)

    # إغلاق الاتصال وتحرير الموارد
    curseur.close()
    connexion.commit()
    # يتم قطع الاتصال
    try:
        connexion.close()
    except MySQLdb.OperationalError,erreur:
        # خطأ آخر
        erreurs[0]+=1
        # رسالة خطأ
        msg="%s : Erreur (%s)" % (requete,erreur)
        erreurs.append(msg)

    # العودة
    return erreurs


# ---------------------------------------------- main
# الاتصال بقاعدة البيانات MySQL
# هوية المستخدم
ID="admpersonnes"
PWD="nobody"
# الجهاز المضيف لنظام إدارة قواعد البيانات
HOTE="localhost"
# هوية قاعدة البيانات
BASE="dbpersonnes"
# معرف ملف الأوامر النصية SQL المطلوب تنفيذه
TEXTE="sql2.txt"


# إنشاء الجدول وتعبئته
erreurs=executerCommandes(HOTE,ID,PWD,BASE,TEXTE,True,False)
#عرض عدد الأخطاء
print "il y a eu %s erreur(s)" % (erreurs[0])
for i in range(1,len(erreurs)):
    print erreurs[i]

ملاحظات:

  • الجديد هو السطر 100 من البرنامج النصي: بعد تنفيذ الأمر SQL، يتم طلب معلومات عن المؤشر المستخدم في هذا الاستعلام. يتم توفير هذه المعلومات بواسطة الدالة afficheInfos في الأسطر 16-40؛
  • السطران 19 و39: إذا كان الاستعلام SQL الذي تم تنفيذه هو SELECT، فإن السمة [curseur.description] هي مصفوفة يصف العنصر رقم i فيها الحقل رقم i من نتيجة الاستعلام SELECT. وإلا، فإن السمة [curseur.rowcount] (السطر 39) هي عدد الأسطر التي تم تعديلها بواسطة الاستعلام INSERT أو UPDATE أو DELETE؛
  • السطران 32 و36: تتيح الطريقة [curseur.fetchone] استرداد السطر الحالي من SELECT. وهناك طريقة [curseur.fetchall] تتيح استردادها دفعة واحدة.

النتائج

ملف الاستعلامات المنفذة:

1
2
3
4
5
6
7
8
9
select * from personnes
select nom,prenom from personnes order by nom asc, prenom desc
select * from personnes where age between 20 and 40 order by age desc, nom asc, prenom asc
insert into personnes values('Josette','Bruneau',46)
update personnes set age=47 where nom='Bruneau'
select * from personnes where nom='Bruneau'
delete from personnes where nom='Bruneau'
select * from personnes where nom='Bruneau'
xselect * from personnes where nom='Bruneau'

نتائج العرض:

select * from personnes : Execution reussie
prenom,nom,age
---------------
('Geraldine', 'Colou', 26L)
('Paulette', 'Girond', 56L)
('Paul', 'Langevin', 48L)
('Sylvie', 'Lefur', 70L)
('Pierre', 'Nicazou', 35L)
select nom,prenom from personnes order by nom asc, prenom desc : Execution reussie
nom,prenom
-----------
('Colou', 'Geraldine')
('Girond', 'Paulette')
('Langevin', 'Paul')
('Lefur', 'Sylvie')
('Nicazou', 'Pierre')
select * from personnes where age between 20 and 40 order by age desc, nom asc,prenom asc : Execution reussie
prenom,nom,age
---------------
('Pierre', 'Nicazou', 35L)
('Geraldine', 'Colou', 26L)
insert into personnes values('Josette','Bruneau',46) : Execution reussie
1 lignes(s) a (ont) ete modifiee(s)
update personnes set age=47 where nom='Bruneau' : Execution reussie
1 lignes(s) a (ont) ete modifiee(s)
select * from personnes where nom='Bruneau' : Execution reussie
prenom,nom,age
---------------
('Josette', 'Bruneau', 47L)
delete from personnes where nom='Bruneau' : Execution reussie
1 lignes(s) a (ont) ete modifiee(s)
select * from personnes where nom='Bruneau' : Execution reussie
prenom,nom,age
---------------
xselect * from personnes where nom='Bruneau' : Erreur ((1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xselect * from personnes where nom='Bruneau'' at line 1"))

التحقق من PhpMyadmin: