Python/MySQL

Posted: أوت 19, 2008 in Tutorials

Python/MySQL

MySQLdb هى Interface بتسمحلك بالتعامل مع MySQL من خلال بايثون

اوكى القصة بدأت ان اتعمل wrap لل MySQL C APIs بصورة OO

فى امثلة لشكل ال APIs

http://mysql-python.sourceforge.net/MySQLdb.html#id5

جميل احنا تعاملنا كله من خلال ال MySQLdb وهى عملت wrap ل _mysql انترفيس لضمان التكافئ مع ال DB API specifications هتكون PEP 249

اولا ال connect

connect(…)

هى المسئولة عن انشاء الإتصال بقاعدة البيانات وبتعمل ريترن ب Connection Object لازم عشان ننشئ اتصال نحتاج شوية معلومات زى ال

  • host

    ودا بيعبر عن الهوست اللى هيتم الإتصال عليه(الإفتراضى localhost )

  • user

    اسم المستخدم (الإفتراضى المستخدم الحالى )

  • passwd

    الباسورد الخاص بإسم المستخدم (افتراضى لايوجد)

  • db

    قاعدة البيانات (الإفتراضى لأ)

  • port

    زى مانت عارف ال MySQL ليها server ودا البورت بيعبر عن ال TCP Port اللى بيستخدمه السرفر وافتراضيا 3306 (عدله لو قمت بتغييره!)

  • ssl

    لإنشاء SSL Connection (ملحوظة :throws exception لو غير مدعم!)

  • compress

    لتفعيل ال compression (الإفتراضى لأ)

  • connect_timeout

    تحدد زمن ال timeout

  • charset

    اذا تم اضافتها هيتم تضمين use_unicode=True

  • sqlmode

    لتحديد ال sqlmode (يفضل تراجع MySQL documentation)

تقدر تحدد الكثير من الإعدادات كل اللى عليك تراجع ال MySQL Documentation

apilevel

بتحدد اى DB API مدعمة ؟ الحالى 2.0

1- اعمل import ل MySQLdb كالتالى

>>> import MySQLdb as ms

انا خليت ms كalias طبعا انت حر فى كيفية الإستدعاء

>>> ms.apilevel

'2.0'

>>> ms.threadsafety

1

اوكى ايه معنى ال threadsafety اصلا ؟

هى عبارة عن رقم بين [0, 3]

0-

بيعنى ان ال threads مش تقدر تشارك فى ال module

1-

ان ال threads تقدر تشارك فى ال module ولكن مش ال connections

2-

ان ال threads تقدر تشارك فى ال module وال connections ولكن مش ال cursors (هنتكلم عنها)

3-

اعلى شئ وهى امكانية المشاركة الكاملة فى ال module, connections و الcursors

paramstyle

سترينج بيعبر عن طريقة التعامل مع ال queries من خلال المدخلات يعنى مثلا احيانا فى ناس بتستخدم

؟ (علامة استفهام) او طريقة %s او حتى استخدام الأرقام :1 و :2 وهكذا (حسب الترتيب) فالديفولت هو format

>>> ms.paramstyle

'format'

ال Exceptions/Errors المرتبطة هنا هما Errors مشتقين من Error

ينقسمو الى

1- IntefaceError ودا بيعبر عن ايرور فى الإنترفيس المستخدمة مش ال داتابيز

2- DatabaseError بيعبر عن ايرور فى قاعدة البيانات وتنقسم لكذا شئ اهمهم

DataError مشاكل مع الداتا

OperationalError ايرور اثناء تنفيذ عملية معينة

ProgrammingError فشل فى تنفيذ sql command معين

NotSupportedError عملية غير مدعمة!

1- ال Connection Objects

هى اوبجكتس بيتم اعادتها عند الإتصال بقاعدة بيانات وليها عدة ميثودز

* close()

لغلق الإتصال

* commit()

لتنفيذ ال transaction الحالى (مش هتفرق فى حال مش فى تدعيم لل transactions اصلا او ال auto commit مفعلة)

*rollback()

الغاء ال transaction الحالى (نفس الملحوظة السابقة ولكن لاحظ فى حال انهاء الإتصال وعدم ال commit هيتم عمل rollback اتوماتيك!)

* cursor()

* set_sql_mode(sqlmode)

بتحدد ال sqlmode (يفضل تراجع ال MySQL documentation )

* set_character_set(charset)

تحديد ال characterset

للحصول على cursor (هنتعرض ليه)

2- ال Cursor Objects

بكل بساطة طالما عندك اتصال بقاعدة بيانات يبقة انت محتاج * تتفاعل * معاها عن طريق تنفيذ SQL statements معينة فال cursor بيقوم بدور الوسيط بينكم بيسمحلك تنفذ SQL statements وبيسمحلك تتعامل مع الrows الناتجة

ال Cursor ليه شوية fields و methods اهمهم

execute(sqlstmt args)

بتقوم بتنفيذ Sql Statement على قاعدة البيانات وبيتم تجهيزها قبل التنفيذ ب args فى حال لو انت قررت تعمل late binding

where name=?

او

where name=:name

وهكذا

rowcount

عدد الصفوف الناتجة من تنفيذ اخر امر

callproc(proc, args)

لإستدعاء stored procedure!

fetchone()

الحصول على صف واحد من الناتج

fetchmany()

للحصول على عدد معين من الصفوف تم تحديده من خلال arraysize (تبع ال cursor وبتعبر عن عدد الصفوف)

arraysize

بتعبر عن رقم الصفوف اللى هيتم اعادته من خلال الfetchmany method

fetchall()

للحصول على كل ال الصفوف الناتجة

rownumber

ال index الخاص ب ال cursor!

نختم بمثال (جزء من برنامج حالى استخدمت فيه MySQL كbackend)

CREATE TABLE `users` (

`id` int(11) NOT NULL auto_increment,

`username` varchar(50) NOT NULL,

`password` varchar(50) NOT NULL,

`state` tinyint(2) NOT NULL,

PRIMARY KEY  (`id`),

UNIQUE KEY `username` (`username`)

) ;

محتاجين نطبق CRUD على الجدول دا من خلال Python/MySQL

Create/Read/Updata/Delete

1- استدعى MySQLdb

import MySQLdb as ms

2- انشئ كلاس DBMan

class DBMan(object):

def __init__(self, dbname="pyim"):

self._dbname=dbname

self._sqlconnection=ms.connect(host="localhost",

user="root",

passwd="",

db="pyim" )

self._sqlcursor=self._sqlconnection.cursor()

لاحظ فى ال constructor محدين اسم ال database ك pyim

وحددنا البيانات وانشئنا Connection object بإسم self._sqlconnection

وحصلنا على cursor منه بإسم self._sqlcursor

إضافة مستخدم جديد

def addUser(self, username, pwd, state=State.Offline):

#State.Offline=1

md5edpass=self._md5(pwd)

sqlstmt="INSERT INTO users VALUES(NULL, '%s', '%s', %d)"%(username, md5edpass, state)

try:

self._sqlcursor.execute(sqlstmt)

self._sqlconnection.commit()

except Exception, e:

print e.message

حذف مستخدم

def deleteUser(self, username):

sqlstmt="DELETE FROM users WHERE username='%s'"%username

try:

self._sqlcursor.execute(sqlstmt)

self._sqlconnection.commit() #commit

except Exception, e:

print e.message

تسجيل دخول

def login(self, username, pwd):

md5edpass=self._md5(pwd)

sqlstmt="SELECT username, password FROM users WHERE username='%s' AND password='%s'"%(username, md5edpass)

self._sqlcursor.execute(sqlstmt)

if self._sqlcursor.fetchone():

self.setState(State.Online, username)

تغيير الحالة

def setState(self, state, username):

        sqlstmt="UPDATE
users SET state=%d WHERE username='%s'"%(state, username)

        try:

self._sqlcursor.execute(sqlstmt)

        except Exception, e:

            print
e.message

عرض الكل

def getAllUsers(self):

        sqlstmt="SELECT
username, state FROM users"

self._sqlcursor.execute(sqlstmt)

        for row in
self._sqlcursor.fetchall():

            yield row[0],
row[1]

ملحوظة: انا هنا ناقشت MySQLdb من خلال مفهوم ال DB API بمعنى ان نفس المبادئ هتلقيها ثابتة فى اى انترفيس هتستخدمها

ومازلنا منتظرين DB API 3

Refs:

MySQLdb 1.2.2 docs

Python DB API Specifications v2

التعليقات
  1. lamia كتب:

    خرافة بس كدة انت شرحت ال DB API 2
    مش مجرد ماى سيكول بس

    ناقص ال setinputsizes, setoutputsize?

  2. ahmed youssef كتب:

    الله يخليكى يالميا انا مش هتكلم فى الداتابيز مع بايثون تانى 😛
    بخصوص ال setinputsizes, setoutputsize
    فدول مش مفعلين فى MySQLdb

  3. Omar كتب:

    شكرا ياأحمد رائع جدا بس ايه مدى دعم بايثون لأوراكل ؟

  4. ahmed youssef كتب:

    شكرا ياعمر بالنسبة للأوركل فانا مش بستخدمها بس شوف
    http://cx-oracle.sourceforge.net/

    وفى سلسلة ماسترينج
    http://www.oracle.com/technology/pub/articles/prez-python-queries.html

    والصفحة دى
    http://wiki.oracle.com/page/python?t=anon

اترك تعليقًا

إملأ الحقول أدناه بالمعلومات المناسبة أو إضغط على إحدى الأيقونات لتسجيل الدخول:

شعار ووردبريس.كوم

أنت تعلق بإستخدام حساب WordPress.com. تسجيل خروج   /  تغيير )

Facebook photo

أنت تعلق بإستخدام حساب Facebook. تسجيل خروج   /  تغيير )

Connecting to %s