Getting started

A simple python script using this library follows:

import mysqlx

# Connect to server on localhost
session = mysqlx.get_session({
    'host': 'localhost',
    'port': 33060,
    'user': 'mike',
    'password': 's3cr3t!'
})

schema = session.get_schema('test')

# Use the collection 'my_collection'
collection = schema.get_collection('my_collection')

# Specify which document to find with Collection.find()
result = collection.find('name like :param').bind('param', 'S%').limit(1).execute()

# Print document
docs = result.fetch_all()
print('Name: {0}'.format(docs[0]['name']))

session.close()

After importing the mysqlx module, we have access to the mysqlx.get_session() function which takes a dictionary object or a connection string with the connection settings. 33060 is the port which the X DevAPI Protocol uses by default. This function returns a mysqlx.Session object on successful connection to a MySQL server, which enables schema management operations, as well as access to the full SQL language if needed.

session = mysqlx.get_session({
    'host': 'localhost',
    'port': 33060,
    'user': 'mike',
    'password': 's3cr3t!'
})

SSL is activated by default. The mysqlx.get_session() will throw an error if the server doesn’t support SSL. To disable SSL, ssl-mode must be manually set to disabled. The mysqlx.SSLMode contains the following SSL Modes: REQUIRED, DISABLED, VERIFY_CA, VERIFY_IDENTITY. Strings (‘required’, ‘disabled’, ‘verify_ca’, ‘verify_identity’) can also be used to specify the ssl-mode option. It is case-insensitive.

SSL is not used if the mode of connection is a Unix Socket since it is already considered secure.

If ssl-ca option is not set, the following SSL Modes are allowed:

  • REQUIRED is set by default.

  • DISABLED connects to the MySQL Server without SSL.

If ssl-ca option is set, only the following SSL Modes are allowed:

  • VERIFY_CA validates the server Certificate with the CA Certificate.

  • VERIFY_IDENTITY verifies the common name on the server Certificate and the hostname.

session = mysqlx.get_session('mysqlx://root:@localhost:33060?ssl-mode=verify_ca&ssl-ca=(/path/to/ca.cert)')
session = mysqlx.get_session({
    'host': 'localhost',
    'port': 33060,
    'user': 'root',
    'password': '',
    'ssl-mode': mysqlx.SSLMode.VERIFY_CA,
    'ssl-ca': '/path/to/ca.cert'
})

The connection settings accepts a connect timeout option connect-timeout, which should be a non-negative integer that defines a time frame in milliseconds. The timeout will assume a default value of 10000 ms (10s) if a value is not provided. And can be disabled if it’s value is set to 0, and in that case, the client will wait until the underlying socket (platform-dependent) times-out.

session = mysqlx.get_session('mysqlx://root:@localhost:33060?connect-timeout=5000')

Connector/Python has a C extension for Protobuf message serialization, this C extension is enabled by default if available. It can be disabled by setting the use-pure option to True.

session = mysqlx.get_session('mysqlx://root:@localhost:33060?use-pure=true')
session = mysqlx.get_session(host='localhost', port=33060, user='root', password='', use_pure=True)
session = mysqlx.get_session({
    'host': 'localhost',
    'port': 33060,
    'user': 'root',
    'password': '',
    'use-pure': True
})

Note

The urllib.parse.quote function should be used to quote special characters for user and password when using a connection string in the mysqlx.get_session() function.

from urllib.parse import quote
session = mysqlx.get_session('mysqlx://root:{0}@localhost:33060?use-pure=true'
                             ''.format(quote('pass?!#%@/')))

The mysqlx.Session.get_schema() method returns a mysqlx.Schema object. We can use this mysqlx.Schema object to access collections and tables. X DevAPI’s ability to chain all object constructions, enables you to get to the schema object in one line. For example:

schema = mysqlx.get_session().get_schema('test')

This object chain is equivalent to the following, with the difference that the intermediate step is omitted:

session = mysqlx.get_session()
schema = session.get_schema('test')

The connection settings accepts a default schema option schema, which should be a valid name for a preexisting schema in the server.

session = mysqlx.get_session('mysqlx://root:@localhost:33060/my_schema')
# or
session = mysqlx.get_session({
    'host': 'localhost',
    'port': 33060,
    'user': 'root',
    'password': '',
    'schema': 'my_schema'
})

Note

The default schema provided must exists in the server otherwise it will raise an error at connection time.

This way the session will use the given schema as the default schema, which can be retrieved by mysqlx.Session.get_default_schema() and also allows to run SQL statements without specifying the schema name:

session = mysqlx.get_session('mysqlx://root:@localhost:33060/my_schema')
my_schema = session.get_default_schema()
assert my_test_schema.get_name() == 'my_schema'
session.sql('CREATE TABLE Pets(name VARCHAR(20))').execute()
# instead of 'CREATE TABLE my_schema.Pets(name VARCHAR(20))'
res = session.sql('SELECT * FROM Pets').execute().fetch_all()
# instead of 'SELECT * FROM my_schema.Pets'

In the following example, the mysqlx.get_session() function is used to open a session. We then get the reference to test schema and create a collection using the mysqlx.Schema.create_collection() method of the mysqlx.Schema object.

# Connecting to MySQL and working with a Session
import mysqlx

# Connect to a dedicated MySQL server
session = mysqlx.get_session({
    'host': 'localhost',
    'port': 33060,
    'user': 'mike',
    'password': 's3cr3t!'
})

schema = session.get_schema('test')

# Create 'my_collection' in schema
schema.create_collection('my_collection')

# Get 'my_collection' from schema
collection = schema.get_collection('my_collection')

The next step would be to run CRUD operations on a collection which belongs to a particular schema. Once we have the mysqlx.Schema object, we can use mysqlx.Schema.get_collection() to obtain a reference to the collection on which we can perform operations like add() or remove().

my_coll = db.get_collection('my_collection')

# Add a document to 'my_collection'
my_coll.add({'_id': '2', 'name': 'Sakila', 'age': 15}).execute()

# You can also add multiple documents at once
my_coll.add({'_id': '2', 'name': 'Sakila', 'age': 15},
            {'_id': '3', 'name': 'Jack', 'age': 15},
            {'_id': '4', 'name': 'Clare', 'age': 37}).execute()

# Remove the document with '_id' = '1'
my_coll.remove('_id = 1').execute()

assert(3 == my_coll.count())

Parameter binding is also available as a chained method to each of the CRUD operations. This can be accomplished by using a placeholder string with a : as a prefix and binding it to the placeholder using the bind() method.

my_coll = db.get_collection('my_collection')
my_coll.remove('name = :data').bind('data', 'Sakila').execute()

Resolving DNS SRV records

If you are using a DNS server with service discovery utility that supports mapping SRV records, you can use the mysqlx+srv scheme or dns-srv connection option and Connector/Python will automatically resolve the available server addresses described by those SRV records.

Note

MySQL host configuration using DNS SRV requires dnspython module.

session = mysqlx.get_session('mysqlx://root:@foo.abc.com')
# or
session = mysqlx.get_session({
    'host': 'foo.abc.com',
    'user': 'root',
    'password': '',
    'dns-srv': True
})

For instance, given the following SRV records by a DNS server at the foo.abc.com endpoint, the servers would be in the following priority: foo2.abc.com, foo1.abc.com, foo3.abc.com, foo4.abc.com.

Record                    TTL   Class    Priority Weight Port  Target
_mysqlx._tcp.foo.abc.com. 86400 IN SRV   0        5      33060 foo1.abc.com
_mysqlx._tcp.foo.abc.com. 86400 IN SRV   0        10     33060 foo2.abc.com
_mysqlx._tcp.foo.abc.com. 86400 IN SRV   10       5      33060 foo3.abc.com
_mysqlx._tcp.foo.abc.com. 86400 IN SRV   20       5      33060 foo4.abc.com

Specifying which TLS versions to use

The desired TLS versions to use during the connection van be specified while getting the session with the use of tls-versions option and in addition the TLS ciphers can also be specified with the tls-ciphersuites option.

session = mysqlx.get_session('mysqlx://root:@127.0.0.1:33060?tls-versions=[TLSv1.1,TLSv1.2]&tls-ciphersuites=[DHE-RSA-AES256-SHA]&ssl-mode=required')
# or
session = mysqlx.get_session({
    'host': '127.0.0.1',
    'user': 'root',
    'password': '',
    'tls-versions"': ["TLSv1.1", "TLSv1.2"],
    'tls-ciphersuites': ["DHE-RSA-AES256-SHA"],
})
res = session.sql("SHOW STATUS LIKE 'Mysqlx_ssl_version'").execute().fetch_all()
print("Mysqlx_ssl_version: {}".format(res[0].get_string('Value')))
res = session.sql("SHOW STATUS LIKE 'Mysqlx_ssl_cipher'").execute().fetch_all()
print("Mysqlx_ssl_cipher: {}".format(res[0].get_string('Value')))
session.close()

From the given list of TLS versions, the highest supported version will be selected for the connection, given as result:

Mysqlx_ssl_version: TLSv1.2

Mysqlx_ssl_cipher: DHE-RSA-AES256-SHA