Skip to content

9. با استفاده از SGBD MySQL

9.1. نصب ماژول MySQLdb

ما قصد داریم با استفاده از پایگاه داده MySQL اسکریپت بنویسیم:

تابع‌های پایتون برای مدیریت پایگاه داده MySQL در ماژولی به نام MySQLdb قرار گرفته‌اند که در توزیع استاندارد پایتون گنجانده نشده است. بنابراین لازم است این ماژول را دانلود و نصب کنید. در اینجا یکی از روش‌های انجام این کار آمده است:

  • از منوی Start، مدیر بسته‌های Python ([1]) را انتخاب کنید. سپس پنجره فرمان ([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
  • خط ۵: بسته mysql-python-1.2.3 در پوشه «%APPDATA%\Python» نصب شده است، که در آن APPDATA پوشه‌ای است که در خط ۸ مشخص شده است.

این عملیات ممکن است در صورت زیر ناموفق باشد:

  • تفسیرگر پایتون مورد استفاده نسخهٔ ۶۴ بیتی باشد؛
  • مسیر %APPDATA% حاوی کاراکترهای دارای علامت باشد.

9.2. نصب MySQL

روش‌های مختلفی برای نصب SGBD MySQL وجود دارد. در اینجا ما از WampServer استفاده کرده‌ایم، بسته‌ای که شامل چندین نرم‌افزار است:

  • یک سرور وب آپاچی. ما از آن برای نوشتن اسکریپت‌های وب با پایتون استفاده خواهیم کرد؛
  • SGBD و MySQL؛
  • زبان اسکریپتی PHP؛
  • یک ابزار اداری برای SGBD MySQL نوشته شده در PHP: phpMyAdmin.

WampServer را می‌توان (ژوئن ۲۰۱۱) از آدرس زیر دانلود کرد:

http://www.wampserver.com/download.php
  • در [1]، نسخه صحیح WampServer را دانلود کنید؛
  • برای [2]، پس از نصب، آن را اجرا کنید. این کار سرور وب آپاچی و 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] که دارای حقوق دسترسی کامل به این پایگاه داده است.

ما قصد داریم اسکریپت‌های پایتون بنویسیم تا با پایگاه داده کار کنیم.

9.3. اتصال به پایگاه داده MySQL - ۱


برنامه (mysqldb_01)


#وارد کردن ماژول MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb

#اتصال به یک پایگاه داده MySQL
....

یادداشت‌ها:

  • خطوط ۲–۴: اسکریپت‌هایی که شامل عملیات مربوط به SGBD و MySQL هستند، باید ماژول MySQLdb را وارد کنند. به یاد داشته باشید که ما این ماژول را در پوشه [%APPDATA%\Python] نصب کردیم. پوشه [%APPDATA%\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

خط ۸: پوشه [site-packages]، جایی که MySQLdb در ابتدا نصب شده بود. ما پوشه [site-packages] را جابجا می‌کنیم، که پوشه‌ای است که ابزار pypm ماژول‌های پایتون را در آن نصب می‌کند. برای افزودن یک پوشه جدید که پایتون در آن به دنبال ماژول‌ها بگردد، آن را به لیست sys.path اضافه می‌کنیم:


#وارد کردن ماژول MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb

#ورود به یک پایگاه داده MySQL
....

در خط ۳، پوشه‌ای را که ماژول 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

  • خطوط ۸–۱۱: اسکریپت (در خط ۱۵) کاربر [admpersonnes / nobody] را به SGBD و MySQL روی ماشین [localhost] متصل می‌کند. این به هیچ پایگاه دادهٔ خاصی متصل نیست؛
  • خطوط ۱۲–۲۴: اتصال ممکن است با شکست مواجه شود. بنابراین، این مورد در یک بلوک try/except/finally مدیریت می‌شود؛
  • خط ۱۵: متد connect از ماژول MySQLdb پارامترهای نام‌گذاری‌شدهٔ مختلفی را می‌پذیرد:
    • user: کاربری که مالک اتصال [admpersonnes] است؛
    • pwd: رمز عبور کاربر [nobody];
    • host: نمونهٔ DBMS MySQL [localhost];
    • db: پایگاه‌دادهٔ مورد اتصال. اختیاری.
  • خط ۱۸: اگر یک استثنا پرتاب شود، از نوع [ MySQLdb.OperationalError] خواهد بود و پیام خطای مربوطه در متغیر [message] یافت می‌شود؛
  • خطوط ۲۰–۲۳: در بند [finally]، اتصال بسته می‌شود. اگر استثنا رخ دهد، گرفته می‌شود (خط ۲۳) اما هیچ اقدامی انجام نمی‌شود (خط ۲۴).

نتایج

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):
    # وارد شده و سپس از پایگاه داده MySQL روی سرور میزبان خارج می‌شود (login, pwd)
    # استثناء 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"
 

# ---------------------------------------------- اصلی
# اتصال به پایگاه داده 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

یادداشت‌ها:

  • خطوط ۷–۱۵: تابعی که تلاش می‌کند کاربر را در SGBD MySQL وارد و سپس خارج کند. نتیجه را نمایش می‌دهد؛
  • خطوط ۱۸–۳۴: برنامهٔ اصلی – متد 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()

# ---------------------------------------------- اصلی
# اتصال به پایگاه داده MySQL
# هویت کاربر
ID="admpersonnes"
PWD="nobody"
# ماشین میزبان DBMS
HOTE="localhost"
#شناسهٔ پایگاه داده
BASE="dbpersonnes"
# اتصال
try:
    connexion=MySQLdb.connect(host=HOTE,user=ID,passwd=PWD,db=BASE)
except MySQLdb.OperationalError,message:
    print message
    sys.exit()

# جدول «people» را در صورت وجود حذف کنید
# اگر وجود نداشته باشد، خطا رخ خواهد داد
# این نادیده گرفته می‌شود
requete="drop table personnes"
try:
    executeSQL(connexion,requete)
except:
    pass
# جدول «people» را ایجاد کنید
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()

یادداشت‌ها:

  • خط ۷: تابع executeSQL یک پرس‌وجو SQL را روی یک اتصال باز اجرا می‌کند؛
  • خط ۱۰: عملیات SQL روی اتصال از طریق یک شیء خاص به نام کرسر انجام می‌شود؛
  • خط ۱۰: یک نشانگر (cursor) به دست می‌آید؛
  • خط ۱۳: پرس‌وجوی SQL اجرا می‌شود؛
  • خط ۱۴: تراکنش جاری commit می‌شود؛
  • خط ۱۵: در صورت وقوع استثنا، پیام خطا در متغیر 'error' ذخیره می‌شود؛
  • خط 16: تراکنش جاری برگشت داده می‌شود؛
  • خط ۱۷: استثنا دوباره پرتاب می‌شود؛
  • خط ۱۹: صرف‌نظر از اینکه خطایی وجود داشته باشد یا خیر، نشانگر بسته می‌شود. این کار منابع مرتبط با آن را آزاد می‌کند.

نتایج

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] و کلید اصلی QZXW2 را دارد.HTMLP000480ZQX.

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, QZXW2HTMLCSuqZQX, PWD, BASE) استفاده می‌کند
    #دستورات SQL موجود در فایل متنی SQL را روی این اتصال اجرا می‌کند
    #این فایل یک فایل فرمان است که حاوی دستورات SQL می‌باشد، هر دستور در یک خط
    # اگر follow=True باشد، هر بار که یک دستور SQL اجرا می‌شود، پیامی نمایش داده می‌شود که نشان می‌دهد آیا موفقیت‌آمیز بوده یا ناموفق
    # اگر stop=True باشد، تابع در اولین خطای یافت‌شده متوقف می‌شود؛ در غیر این صورت، تمام دستورات SQL اجرا می‌شوند
    #تابع یک لیست (تعداد خطاها، خطا۱، خطا۲، ...) را بازمی‌گرداند

    #بررسی می‌کند که آیا فایل 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


# ---------------------------------------------- اصلی
#اتصال به پایگاه داده MySQL
#شناسهٔ کاربر
ID="admpersonnes"
PWD="nobody"
# ماشین میزبان DBMS
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)

یک خطا عمداً در خط ۵ وارد شده است.

خروجی صفحه:

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 است
        # توضیحات [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,QZXW2HTMLCSuqZQX,PWD,BASE) استفاده می‌کند
    #دستورات SQL را که در فایل متنی SQL در این اتصال قرار دارند، اجرا می‌کند
    #این فایل یک فایل فرمان است که حاوی دستورات SQL می‌باشد و باید هر دستور به‌صورت جداگانه در هر خط اجرا شود
    # اگر 'follow-up=1' باشد، هر بار که یک دستور SQL اجرا می‌شود، پیامی نمایش داده می‌شود که نشان می‌دهد آیا عملیات موفق بوده یا ناموفق
    # اگر stop=1 باشد، تابع در اولین خطای یافت‌شده متوقف می‌شود؛ در غیر این صورت، تمام دستورات SQL اجرا می‌شوند
    #تابع یک آرایه را بازمی‌گرداند (تعداد خطاها، خطا۱، خطا۲، …)

    #بررسی می‌کند که آیا فایل 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


# ---------------------------------------------- اصلی
# اتصال به پایگاه داده MySQL
#شناسهٔ کاربر
ID="admpersonnes"
PWD="nobody"
# ماشین میزبان DBMS
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]

یادداشت‌ها:

  • ویژگی جدید در خط ۱۰۰ اسکریپت قرار دارد: پس از اجرای دستور SQL، اطلاعاتی درباره نشانگر مورد استفاده توسط این پرس‌وجو درخواست می‌شود. این اطلاعات توسط تابع afficheInfos در خطوط ۱۶–۴۰ ارائه می‌شود؛
  • خطوط ۱۹ و ۳۹: اگر پرس‌وجوی اجرا شده SQL یک SELECT بود، ویژگی [curseur.description] یک آرایه است که در آن عنصر با شماره i، شماره فیلد i از نتیجه SELECT را توصیف می‌کند. در غیر این صورت، ویژگی [curseur.rowcount] (خط ۳۹) تعداد سطرهایی است که توسط پرس‌وجوی INSERT، UPDATE یا DELETE اصلاح شده‌اند؛
  • خطوط ۳۲ و ۳۶: متد [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 را بررسی کنید: