Skip to content

Commit a22bd4a

Browse files
NicorettikaklakariadaSebastian Bärtkilias
authored
Add support for pyexasol part 2/2 (#320)
* Add hooks for websocket based exasol dialect * Add support for enabling and disabling certificate validation * Add hooks for type conversions between pyexasol and dbapi2 cursor * Add websocket dialect/connector to ci/cd matrix * Update dependencies * Update README.md * Rework dbapi2 types * Restructure the dbapi2 module of the websocket driver * Disable remaining failing SQLA compliance tests - #341 - #342 --- Co-authored-by: Christoph Pirkl <[email protected]> Co-authored-by: Sebastian Bär <[email protected]> Co-authored-by: Torsten Kilias <[email protected]>
1 parent 302b2e3 commit a22bd4a

29 files changed

+2005
-1316
lines changed

.github/workflows/ci-cd.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ jobs:
6464
connector:
6565
- pyodbc
6666
- turbodbc
67+
- websocket
6768
exasol_version:
6869
- 7.1.17
6970
- 7.0.20

.github/workflows/ci.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ jobs:
6868
connector:
6969
- pyodbc
7070
- turbodbc
71+
- websocket
7172
exasol_version:
7273
- 7.1.17
7374
- 7.0.20

CHANGELOG.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@
33
Unreleased
44
==========
55

6+
* Add Beta version of websocket based dialect
7+
8+
**🚨 Attention:**
9+
10+
This feature is currently in Beta, therefore it should not be used in production.
11+
We also recommend to have a look into the known issues, before you start using it.
12+
13+
If you encounter any problem, please `create an issue <https://github.com/exasol/sqlalchemy-exasol/issues/new?assignees=&labels=bug&projects=&template=bug.md&title=%F0%9F%90%9E+%3CInsert+Title%3E>`_.
14+
With your feedback, we will be able stabilize this feature more quickly.
15+
16+
617
.. _changelog-4.4.0:
718

819
4.4.0 — 2023-05-16

README.rst

Lines changed: 111 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ SQLAlchemy Dialect for EXASOL DB
2626
:target: https://pycqa.github.io/isort/
2727
:alt: Formatter - Isort
2828

29-
.. image:: https://img.shields.io/badge/pylint-5.8-yellow
29+
.. image:: https://img.shields.io/badge/pylint-6.4-yellowgreen
3030
:target: https://github.com/PyCQA/pylint
3131
:alt: Pylint
3232

@@ -49,17 +49,6 @@ How to get started
4949
We assume you have a good understanding of (unix)ODBC. If not, make sure you
5050
read their documentation carefully - there are lot's of traps 🪤 to step into.
5151

52-
Meet the system requirements
53-
````````````````````````````
54-
55-
On Linux/Unix like systems you need:
56-
57-
- Python
58-
- An Exasol DB (e.g. `docker-db <test_docker_image_>`_ or a `cloud instance <test_drive_>`_)
59-
- The packages unixODBC and unixODBC-dev >= 2.2.14
60-
- The Exasol `ODBC driver <odbc_driver_>`_
61-
- The ODBC.ini and ODBCINST.ini configurations files setup
62-
6352
Turbodbc support
6453
````````````````
6554

@@ -72,6 +61,18 @@ Turbodbc support
7261
`test/test_update.py <test/test_update.py>`_ for an example
7362

7463

64+
65+
Meet the system requirements
66+
````````````````````````````
67+
68+
On Linux/Unix like systems you need:
69+
70+
- Python
71+
- An Exasol DB (e.g. `docker-db <test_docker_image_>`_ or a `cloud instance <test_drive_>`_)
72+
- The packages unixODBC and unixODBC-dev >= 2.2.14
73+
- The Exasol `ODBC driver <odbc_driver_>`_
74+
- The ODBC.ini and ODBCINST.ini configurations files setup
75+
7576
Setup your python project and install sqlalchemy-exasol
7677
```````````````````````````````````````````````````````
7778

@@ -109,18 +110,17 @@ The dialect supports two types of connection urls creating an engine. A DSN (Dat
109110

110111
.. list-table::
111112

112-
* - Type
113-
- Example
114-
* - DSN URL
115-
- 'exa+pyodbc://USER:PWD@exa_test'
116-
* - HOST URL
117-
- 'exa+pyodbc://USER:[email protected]:1234/my_schema?parameter'
113+
* - Type
114+
- Example
115+
* - DSN URL
116+
- 'exa+pyodbc://USER:PWD@exa_test'
117+
* - HOST URL
118+
- 'exa+pyodbc://USER:[email protected]:1234/my_schema?parameter'
118119

119120
Features
120121
++++++++
121122

122123
- SELECT, INSERT, UPDATE, DELETE statements
123-
- you can even use the MERGE statement (see unit tests for examples)
124124

125125
Notes
126126
+++++
@@ -139,3 +139,95 @@ Development & Testing
139139
`````````````````````
140140
See `developer guide`_
141141

142+
Websocket support
143+
-----------------
144+
145+
.. attention::
146+
147+
The Websocket support is currently in Beta, therefore it should not be used in production.
148+
We also recommend to have a look into the known issues, before you start using it.
149+
150+
If you encounter any issue, please `create an issue <https://github.com/exasol/sqlalchemy-exasol/issues/new?assignees=&labels=bug&projects=&template=bug.md&title=%F0%9F%90%9E+%3CInsert+Title%3E>`_.
151+
With your feedback, we will be able to stabilize this feature more quickly.
152+
153+
What is Websocket support?
154+
``````````````````````````
155+
In the context of SQLA and Exasol, Websocket support means that an SQLA dialect
156+
supporting the `Exasol Websocket Protocol <https://github.com/exasol/websocket-api>`_
157+
is provided.
158+
159+
Using the websocket based protocol instead over ODBC will provide various advantages:
160+
161+
* Less System Dependencies
162+
* Easier to use than ODBC based driver(s)
163+
* Lock free metadata calls etc.
164+
165+
For further details `Why a Websockets API <https://github.com/exasol/websocket-api#why-a-websockets-api>`_.
166+
167+
Examples Usage(s)
168+
`````````````````
169+
170+
.. code-block:: python
171+
172+
from sqla import create_engine
173+
174+
engine = create_engine("exa+websocket://sys:[email protected]:8888")
175+
with engine.connect() as con:
176+
...
177+
178+
.. code-block:: python
179+
180+
from sqla import create_engine
181+
182+
# ATTENTION:
183+
# In terms of security it is NEVER a good idea to turn of certificate validation!!
184+
# In rare cases it may be handy for non-security related reasons.
185+
# That said, if you are not a 100% sure about your scenario, stick with the
186+
# secure defaults.
187+
# In most cases, having a valid certificate and/or configuring the truststore(s)
188+
# appropriately is the best/correct solution.
189+
engine = create_engine("exa+websocket://sys:[email protected]:8888?SSLCertificate=SSL_VERIFY_NONE")
190+
with engine.connect() as con:
191+
...
192+
193+
Supported Connection Parameters
194+
```````````````````````````````
195+
.. list-table::
196+
197+
* - Parameter
198+
- Values
199+
- Comment
200+
* - ENCRYPTION
201+
- Y, Yes, N, No
202+
- Y or Yes Enable Encryption (TLS) default, N or No disable Encryption
203+
* - SSLCertificate
204+
- SSL_VERIFY_NONE
205+
- Disable certificate validation
206+
207+
208+
Known Issues
209+
````````````
210+
211+
* Literal casts within prepared statements do not work
212+
- :code:`INSERT INTO t (x) VALUES (CAST(? AS VARCHAR(50)));`
213+
* Various conversions regarding float, decimals
214+
- Certain scenarios still yield a :code:`string` type instead :code:`float` or :code:`decimal` type.
215+
* Insert
216+
- Insert multiple rows via prepared statements does not work in all cases
217+
- Insert from SELECT does not work
218+
* For some prepared statements, the wss protocol type conversion does not work properly
219+
- Error messages usually state some JSON type mismatch, e.g.: '... getString: JSON value is not a string ...'
220+
* Known failing tests of the SQLA compliance test suite
221+
- FAILED test/integration/sqlalchemy/test_suite.py::CastTypeDecoratorTest_exasol+exasol_driver_websocket_dbapi2::test_special_type - sqlalchemy.exc.DBAPIError: (exasol.driver.websocket._errors.Error)
222+
- FAILED test/integration/sqlalchemy/test_suite.py::ExistsTest_exasol+exasol_driver_websocket_dbapi2::test_select_exists - sqlalchemy.exc.DBAPIError: (exasol.driver.websocket._errors.Error)
223+
- FAILED test/integration/sqlalchemy/test_suite.py::ExistsTest_exasol+exasol_driver_websocket_dbapi2::test_select_exists_false - sqlalchemy.exc.DBAPIError: (exasol.driver.websocket._errors.Error)
224+
- FAILED test/integration/sqlalchemy/test_suite.py::InsertBehaviorTest_exasol+exasol_driver_websocket_dbapi2::test_empty_insert_multiple - sqlalchemy.exc.DBAPIError: (exasol.driver.websocket._errors.Error)
225+
- ERROR test/integration/sqlalchemy/test_suite.py::InsertBehaviorTest_exasol+exasol_driver_websocket_dbapi2::test_empty_insert_multiple_teardown - ERROR
226+
- FAILED test/integration/sqlalchemy/test_suite.py::InsertBehaviorTest_exasol+exasol_driver_websocket_dbapi2::test_insert_from_select - sqlalchemy.exc.DBAPIError: (exasol.driver.websocket._errors.Error)
227+
- FAILED test/integration/sqlalchemy/test_suite.py::InsertBehaviorTest_exasol+exasol_driver_websocket_dbapi2::test_insert_from_select_with_defaults - sqlalchemy.exc.DBAPIError: (exasol.driver.websocket._errors.Error)
228+
- FAILED test/integration/sqlalchemy/test_suite.py::NumericTest_exasol+exasol_driver_websocket_dbapi2::test_float_as_decimal - sqlalchemy.exc.DBAPIError: (exasol.driver.websocket._errors.Error)
229+
- FAILED test/integration/sqlalchemy/test_suite.py::NumericTest_exasol+exasol_driver_websocket_dbapi2::test_float_as_float - sqlalchemy.exc.DBAPIError: (exasol.driver.websocket._errors.Error)
230+
- FAILED test/integration/sqlalchemy/test_suite.py::NumericTest_exasol+exasol_driver_websocket_dbapi2::test_float_coerce_round_trip - AssertionError: '15.7563' != 15.7563
231+
- FAILED test/integration/sqlalchemy/test_suite.py::NumericTest_exasol+exasol_driver_websocket_dbapi2::test_float_custom_scale - sqlalchemy.exc.DBAPIError: (exasol.driver.websocket._errors.Error)
232+
- FAILED test/integration/sqlalchemy/test_suite.py::NumericTest_exasol+exasol_driver_websocket_dbapi2::test_numeric_as_float - AssertionError: {'15.7563'} != {15.7563}
233+
- FAILED test/integration/sqlalchemy/test_suite.py::NumericTest_exasol+exasol_driver_websocket_dbapi2::test_render_literal_numeric_asfloat - AssertionError: assert '15.7563' in [15.7563]

0 commit comments

Comments
 (0)