Chapter 9 Connector/Python Other Topics

Table of Contents

9.1 Connector/Python Connection Pooling
9.2 Connector/Python Fabric Support
9.3 Connector/Python Django Backend

This section describes additional Connection/Python features:

9.1 Connector/Python Connection Pooling

MySQL Connector/Python 1.1.1 and up supports simple connection pooling that has these characteristics:

  • The mysql.connector.pooling module implements pooling.

  • A pool opens a number of connections and handles thread safety when providing connections to requesters.

  • The size of a connection pool is configurable at pool creation time. It cannot be resized thereafter.

  • A connection pool can be named at pool creation time. If no name is given, one is generated using the connection parameters.

  • The connection pool name can be retrieved from the connection pool or connections obtained from it.

  • It is possible to have multiple connection pools. This enables applications to support pools of connections to different MySQL servers, for example.

  • For each connection request, the pool provides the next available connection. No round-robin or other scheduling algorithm is used. If a pool is exhausted, a PoolError is raised.

  • It is possible to reconfigure the connection parameters used by a pool. These apply to connections obtained from the pool thereafter. Reconfiguring individual connections obtained from the pool by calling the connection config() method is not supported.

Applications that can benefit from connection-pooling capability include:

  • Middleware that maintains multiple connections to multiple MySQL servers and requires connections to be readily available.

  • Web sites that can have more permanent connections open to the MySQL server.

A connection pool can be created implicitly or explicitly.

To create a connection pool implicitly: Open a connection and specify one or more pool-related arguments (pool_name, pool_size). For example:

dbconfig = {
  "database": "test",
  "user":     "joe"
}

cnx = mysql.connector.connect(pool_name = "mypool",
                              pool_size = 3,
                              **dbconfig)

The pool name is restricted to alphanumeric characters and the special characters ., _, *, $, and #. The pool name must be no more than pooling.CNX_POOL_MAXNAMESIZE characters long (default 64).

The pool size must be greater than 0 and less than pooling.CNX_POOL_MAXSIZE (default 32).

With either the pool_name or pool_size argument present, Connector/Python creates the new pool. If the pool_name argument is not given, the connect() call automatically generates the name, composed from whichever of the host, port, user, and database connection arguments are given, in that order. If the pool_size argument is not given, the default size is 5 connections.

Subsequent calls to connect() that name the same connection pool return connections from the existing pool. Any pool_size or connection parameter arguments are ignored, so the following connect() calls are equivalent to the original connect() call shown earlier:

cnx = mysql.connector.connect(pool_name = "mypool", pool_size = 3)
cnx = mysql.connector.connect(pool_name = "mypool", **dbconfig)
cnx = mysql.connector.connect(pool_name = "mypool")

Pooled connections obtained by calling connect() with a pool-related argument have a class of PooledMySQLConnection (see Section 10.4, “pooling.PooledMySQLConnection Class”). PooledMySQLConnection pooled connection objects are similar to MySQLConnection unpooled connection objects, with these differences:

  • To release a pooled connection obtained from a connection pool, invoke its close() method, just as for any unpooled connection. However, for a pooled connection, close() does not actually close the connection but returns it to the pool and makes it available for subsequent connection requests.

  • A pooled connection cannot be reconfigured using its config() method. Connection changes must be done through the pool object itself, as described shortly.

  • A pooled connection has a pool_name property that returns the pool name.

To create a connection pool explicitly: Create a MySQLConnectionPool object (see Section 10.3, “pooling.MySQLConnectionPool Class”):

dbconfig = {
  "database": "test",
  "user":     "joe"
}

cnxpool = mysql.connector.pooling.MySQLConnectionPool(pool_name = "mypool",
                                                      pool_size = 3,
                                                      **dbconfig)

To request a connection from the pool, use its get_connection() method:

cnx1 = cnxpool.get_connection()
cnx2 = cnxpool.get_connection()

When you create a connection pool explicitly, it is possible to use the pool object's set_config() method to reconfigure the pool connection parameters:

dbconfig = {
  "database": "performance_schema",
  "user":     "admin",
  "password": "secret"
}

cnxpool.set_config(**dbconfig)

Connections requested from the pool after the configuration change use the new parameters. Connections obtained before the change remain unaffected, but when they are closed (returned to the pool) are reopened with the new parameters before being returned by the pool for subsequent connection requests.

9.2 Connector/Python Fabric Support

MySQL Fabric is a system for managing a farm of MySQL servers (and other components). Fabric provides an extensible and easy to use system for managing a MySQL deployment for sharding and high-availability.

Connector/Python 1.2.0 and up supports Fabric and provides these capabilities:

  • Requesting a connection to a MySQL server managed by Fabric is as transparent as possible to users already familiar with Connector/Python.

  • Connector/Python is able to get a MySQL server connection given a high-availability group and a mode specifying whether the connection is read-only or also permits updates (read-write).

  • Connector/Python supports sharding and is able to find the correct MySQL server for a given table or tables and key based on scope (local or global) and mode (read-only or read-write). RANGE and HASH mechanisms are supported transparently to the user.

  • Among secondary MySQL servers in the same group, load balancing of read-only operations occurs based on server weight.

  • Faulty MySQL servers are reported to Fabric, and failover is supported when failure occurs for a server in a group.

  • Connector/Python caches information coming from Fabric to speed up operations. Failures connecting to a MySQL server reset this cache. The time to live for cached information can be set by Fabric, or a default is used otherwise.

  • Fabric support applies to versions of Python supported by Connector/Python itself (see Chapter 3, Connector/Python Versions). In particular, you can use Connector/Python with Python 3.1 and later to establish Fabric connections, even though Fabric does not support Python 3.

For more information, see MySQL Fabric.

9.3 Connector/Python Django Backend

Connector/Python 1.1.1 and up includes a mysql.connector.django module that provides a Django backend for MySQL. This backend supports new features found in MySQL 5.6 such as fractional seconds support for temporal data types.

Django Configuration

Django uses a configuration file named settings.py that contains a variable called DATABASES (see https://docs.djangoproject.com/en/1.5/ref/settings/#std:setting-DATABASES). To configure Django to use Connector/Python as the MySQL backend, the example found in the Django manual can be used as a basis:

DATABASES = {
    'default': {
        'NAME': 'user_data',
        'ENGINE': 'mysql.connector.django',
        'USER': 'mysql_user',
        'PASSWORD': 'priv4te',
        'OPTIONS': {
          'autocommit': True,
        },
    }
}

It is possible to add more connection arguments using OPTIONS.

Support for MySQL Features

Django can launch the MySQL client application mysql. When the Connector/Python backend does this, it arranges for the sql_mode system variable to be set to TRADITIONAL at startup.

Some MySQL features are enabled depending on the server version. For example, support for fractional seconds precision is enabled when connecting to a server from MySQL 5.6.4 or higher. Django's DateTimeField is stored in a MySQL column defined as DATETIME(6), and TimeField is stored as TIME(6). For more information about fractional seconds support, see Fractional Seconds in Time Values.

Django Unit Testing

Django comes with an extensive set of unit tests. To run these, use the run_django_tests.py script located in the Connector/Python distribution support/django directory. For example, to run the basic tests using Django 1.5, run the following commands:

shell> cd support/django
shell> python run_django_tests.py --django 1.5 --tests basic

The script can be run using Python 2 or Python 3. It downloads Django, unpacks it and starts the tests. To avoid the download and use an already-fetched version, use the --offline option.

To see the script requirements, run it with the --help option, or examine the script itself. Here is an overview:

  • Two MySQL servers, configured as a master/slave pair

  • A database named django_tests on each server

To alter the settings of the MySQL servers, modify the file test_mysqlconnector_settings.py, also located in the support/django directory.