Quantcast
Channel: Geert JM Vanderkelen » Geert Vanderkelen
Viewing all articles
Browse latest Browse all 25

Connector/Python 2.1.1 Alpha released with C Extension

$
0
0

MySQL Connector/Python 2.1.1 took a while to release and that was because we had to add some more packages which contains the optional C Extension. Note that this is still Alpha and we want you guys to report any problems and requests.

The Connector/Python C Extension was added because in certain situations, for example reading a huge result set, can take a long time with pure Python. That’s why we choose to interface with Connector/C (libmysqlclient).

Note: Pure Python is still default and it will be kept that way!

Installing Connector/Python 2.1 didn’t change much:

shell> python setup.py install

If you’d like the C Extension, you have to first install MySQL Connector/C or have the MySQL Server development packages available. Careful with mixing 32 and 64-bit: make sure Python matches your MySQL libraries. Connector/Python will try to detect the mismatch and notify you.

For example, on OS X with development tools installed, I would do the following:

shell> virtualenv CPYENV
shell> source CPYENV/bin/activate
shell> tar xzf ~/Downloads/mysql-connector-c-6.1.5-osx10.7-x86_64.tar.gz
shell> tar xzf ~/Downloads/mysql-connector-python-2.1.1.tar.gz
shell> cd mysql-connector-2.1.1
shell> python setup.py install --with-mysql-capi=../mysql-connector-c-6.1.5-osx10.7-x86_64

If all goes well, the above would have compiled and install the C Extension together with the pure Python code inside a virtual environment. Here is how you can check if the C Extension is available:

>>> import mysql.connector
>>> mysql.connector.HAVE_CEXT
True

If you want to see the speed improvements, you can load up the employees sample database and do the following in the Python interpreter:

shell> python
>>> import mysql.connector
>>> cnx = mysql.connector.connect(user='root', database='employees')
>>> cnxc = mysql.connector.connect(use_pure=False, user='root', database='employees')
>>> cur = cnx.cursor()
>>> q = "SELECT * FROM salaries"
>>> s=time(); cur.execute(q); r=cur.fetchall(); print("%.2f" % (time()-s))
65.57
>>> cur = cnxc.cursor()
>>> s=time(); cur.execute(q); r=cur.fetchall(); print("%.2f" % (time()-s))
13.09

That’s 66 seconds vs. 13 seconds using the C Extension.

If that is not fast enough, and it is not, you can directly load the C Extension and use the wrapper around the MySQL C API (see manual). Here’s an example:

>>> import _mysql_connector
>>> cnx = _mysql_connector.MySQL()
>>> cnx.connect(user='root', database='employees')
>>> cnx.query("SELECT emp_no, last_name, hire_date FROM employees")
True
>>> cnx.fetch_row()
(10001, 'Facello', datetime.date(1986, 6, 26))
>>> cnx.free_result()
>>> cnx.close()

It is a bit different than using mysql.connector, but notice that result coming from the C Extension is also converted to Python data types.

How fast is using _mysql_connector? Lets say we want the raw data, save the following to a Python script file and execute:

from time import time
import _mysql_connector
cnx = _mysql_connector.MySQL(raw=True)
cnx.connect(user='root', database='employees')
cnx.query("SELECT * FROM salaries")
s = time()
row = cnx.fetch_row()
while row:
  row = cnx.fetch_row()
cnx.free_result()

print("All fetched in %.2fs" % (time() - s))

cnx.close()

The output would be something like this:

All fetched in 2.25s

If you put it all together, and this is not scientific, just on my OS X MacBook, SELECT * FORM salaries:

  • Pure Python, not raw: 66 seconds
  • Using C Extension with PEP-249, not raw 13 seconds
  • Using C Extension directly, not raw: 12 seconds
  • Using C Extension, raw: 3 seconds

If you want to dump big sets of data, and you want to do it the Python way, you can use the C Extension to get it faster.

Yes, the C Extension works and compiles on Windows!


Viewing all articles
Browse latest Browse all 25

Trending Articles