Getting started =============== A simple python script using this library follows: .. code-block:: python 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 :func:`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 :class:`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. .. code-block:: python session = mysqlx.get_session({ 'host': 'localhost', 'port': 33060, 'user': 'mike', 'password': 's3cr3t!' }) SSL is activated by default. The :func:`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 :class:`mysqlx.SSLMode` contains the following SSL Modes: :data:`REQUIRED`, :data:`DISABLED`, :data:`VERIFY_CA`, :data:`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: - :data:`REQUIRED` is set by default. - :data:`DISABLED` connects to the MySQL Server without SSL. If ``ssl-ca`` option is set, only the following SSL Modes are allowed: - :data:`VERIFY_CA` validates the server Certificate with the CA Certificate. - :data:`VERIFY_IDENTITY` verifies the common name on the server Certificate and the hostname. .. code-block:: python 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. .. code-block:: python 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 :data:`True`. .. code-block:: python 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 :func:`mysqlx.get_session()` function. .. code-block:: python from urllib.parse import quote session = mysqlx.get_session('mysqlx://root:{0}@localhost:33060?use-pure=true' ''.format(quote('pass?!#%@/'))) The :func:`mysqlx.Session.get_schema()` method returns a :class:`mysqlx.Schema` object. We can use this :class:`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: .. code-block:: python schema = mysqlx.get_session().get_schema('test') This object chain is equivalent to the following, with the difference that the intermediate step is omitted: .. code-block:: python 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. .. code-block:: python 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 :func:`mysqlx.Session.get_default_schema()` and also allows to run SQL statements without specifying the schema name: .. code-block:: python 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 :func:`mysqlx.get_session()` function is used to open a session. We then get the reference to ``test`` schema and create a collection using the :func:`mysqlx.Schema.create_collection()` method of the :class:`mysqlx.Schema` object. .. code-block:: python # 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 :class:`mysqlx.Schema` object, we can use :func:`mysqlx.Schema.get_collection()` to obtain a reference to the collection on which we can perform operations like :func:`add()` or :func:`remove()`. .. code-block:: python 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 :func:`bind()` method. .. code-block:: python 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. .. code-block:: python 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. .. code-block:: python 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