File: getting_started.rst

package info (click to toggle)
mysql-connector-python 9.5.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 28,308 kB
  • sloc: python: 86,729; sql: 47,030; ansic: 3,494; cpp: 860; sh: 394; makefile: 208; javascript: 2
file content (241 lines) | stat: -rw-r--r-- 10,510 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
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 <https://developers.google.com/protocol-buffers/>`_ 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 <https://docs.python.org/3/library/urllib.parse.html#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 <https://tools.ietf.org/html/rfc2782>`_, 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 <http://www.dnspython.org/>`_ 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