Skip to content

Commit 6e22f20

Browse files
authored
Refactoring/637 update dependency declaration pyexasol (#644)
* Update dependency declaration to `pyexasol` * Set websocket_sslopt={"cert_reqs": ssl.CERT_NONE} in tests * Add option to pass on fingerprint in websocket connection * Reorganize documentation & add part about fingerprint to websocket-based dialect * Prepare release 5.2.0 * Simplify test as always args = [] * Add unit test for websocket fingerprint usage * Simplify tests to highlight difference between use cases
1 parent 2a64b97 commit 6e22f20

File tree

14 files changed

+412
-244
lines changed

14 files changed

+412
-244
lines changed

README.rst

Lines changed: 10 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -45,141 +45,40 @@ SQLAlchemy Dialect for EXASOL DB
4545

4646
Getting Started with SQLAlchemy-Exasol
4747
--------------------------------------
48-
SQLAlchemy-Exasol supports multiple dialects, primarily differentiated by whether they are ODBC or Websocket based.
48+
SQLAlchemy-Exasol supports multiple dialects, primarily differentiated by whether they are ODBC or Websocket-based.
4949

5050
Choosing a Dialect
5151
++++++++++++++++++
5252

53-
We recommend using the Websocket-based dialect due to its simplicity. ODBC-based dialects demand a thorough understanding of (Unix)ODBC, and the setup is considerably more complex.
53+
We recommend using the Websocket-based dialect due to its simplicity.
54+
ODBC-based dialects demand a thorough understanding of (Unix)ODBC, and the setup is considerably more complex.
5455

5556
.. warning::
5657

57-
The maintenance of Turbodbc support is currently paused, and it may be phased out in future versions.
58-
We are also planning to phase out the pyodbc support in the future.
59-
58+
The maintenance of Turbodbc & pyodbc support is currently paused, and it is planned to be phased out in future versions.
6059

6160

6261
System Requirements
6362
-------------------
64-
- Python
65-
- An Exasol DB (e.g. `docker-db <test_docker_image_>`_ or a `cloud instance <test_drive_>`_)
63+
- Exasol >= 7.1 (e.g. `docker-db <test_docker_image_>`_ or a `cloud instance <test_drive_>`_)
64+
- Python >= 3.10
6665

6766
.. note::
6867

6968
For ODBC-Based Dialects, additional libraries required for ODBC are necessary
7069
(for further details, checkout the `developer guide`_).
7170

72-
Setting Up Your Python Project
73-
------------------------------
74-
75-
Install SQLAlchemy-Exasol:
76-
77-
.. code-block:: shell
78-
79-
$ pip install sqlalchemy-exasol
80-
81-
.. note::
82-
83-
To use an ODBC-based dialect, you must specify it as an extra during installation.
84-
85-
.. code-block:: shell
86-
87-
pip install "sqlalchemy-exasol[pydobc]"
88-
pip install "sqlalchemy-exasol[turbodbc]"
89-
90-
91-
Using SQLAlchemy with EXASOL DB
92-
-------------------------------
93-
94-
**Websocket based Dialect:**
95-
96-
.. code-block:: python
97-
98-
from sqlalchemy import create_engine
99-
url = "exa+websocket://A_USER:[email protected]:1234/my_schema?CONNECTIONLCALL=en_US.UTF-8"
100-
e = create_engine(url)
101-
query = "select 42 from dual"
102-
with engine.connect() as con:
103-
result = con.execute(sql.text(query)).fetchall()
104-
105-
Examples:
106-
107-
.. code-block:: python
108-
109-
from sqlalchemy import create_engine
110-
111-
engine = create_engine("exa+websocket://sys:[email protected]:8888")
112-
113-
# don't rely on autocommit for DML and DDL
114-
with engine.begin() as con:
115-
...
116-
117-
# for non-DML or non-DDL queries
118-
with engine.connect() as con:
119-
...
120-
121-
.. code-block:: python
122-
123-
from sqlalchemy import create_engine
124-
125-
# ATTENTION:
126-
# In terms of security it is NEVER a good idea to disable certificate validation!!
127-
# In rare cases it may be handy for non-security related reasons.
128-
# That said, if you are not a 100% sure about your scenario, stick with the
129-
# secure defaults.
130-
# In most cases, having a valid certificate and/or configuring the truststore(s)
131-
# appropriately is the best/correct solution.
132-
engine = create_engine("exa+websocket://sys:[email protected]:8888?SSLCertificate=SSL_VERIFY_NONE")
133-
with engine.connect() as con:
134-
...
135-
136-
137-
**Pyodbc (ODBC based Dialect):**
138-
139-
.. code-block:: python
140-
141-
from sqlalchemy import create_engine
142-
url = "exa+pyodbc://A_USER:[email protected]:1234/my_schema?CONNECTIONLCALL=en_US.UTF-8&driver=EXAODBC"
143-
e = create_engine(url)
144-
query = "select 42 from dual"
145-
with engine.connect() as con:
146-
result = con.execute(sql.text(query)).fetchall()
147-
148-
**Turbodbc (ODBC based Dialect):**
149-
150-
.. code-block:: python
151-
152-
from sqlalchemy import create_engine
153-
url = "exa+turbodbc://A_USER:[email protected]:1234/my_schema?CONNECTIONLCALL=en_US.UTF-8&driver=EXAODBC"
154-
e = create_engine(url)
155-
query = "select 42 from dual"
156-
with engine.connect() as con:
157-
result = con.execute(sql.text(query)).fetchall()
158-
159-
16071
Features
16172
--------
16273

16374
- SELECT, INSERT, UPDATE, DELETE statements
16475

165-
General Notes
166-
-------------
76+
Getting Started
77+
---------------
16778

168-
- Schema name and parameters are optional for the host url
169-
- At least on Linux/Unix systems it has proven valuable to pass 'CONNECTIONLCALL=en_US.UTF-8' as a url parameter. This will make sure that the client process (Python) and the EXASOL driver (UTF-8 internal) know how to interpret code pages correctly.
170-
- Always use all lower-case identifiers for schema, table and column names. SQLAlchemy treats all lower-case identifiers as case-insensitive, the dialect takes care of transforming the identifier into a case-insensitive representation of the specific database (in case of EXASol this is upper-case as for Oracle)
171-
- As of Exasol client driver version 4.1.2 you can pass the flag 'INTTYPESINRESULTSIFPOSSIBLE=y' in the connection string (or configure it in your DSN). This will convert DECIMAL data types to Integer-like data types. Creating integers is a factor three faster in Python than creating Decimals.
79+
Check out sqlalchemy-exasols's [User Guide(https://exasol.github.io/sqlalchemy-exasol/master/user_guide.html) page for your first steps.
17280

17381
.. _developer guide: https://github.com/exasol/sqlalchemy-exasol/blob/master/doc/developer_guide/developer_guide.rst
82+
.. _test_docker_image: https://github.com/exasol/docker-db
17483
.. _odbc_driver: https://docs.exasol.com/db/latest/connect_exasol/drivers/odbc/odbc_linux.htm
17584
.. _test_drive: https://cloud.exasol.com/signup
176-
.. _test_docker_image: https://github.com/exasol/docker-db
177-
178-
Known Issues
179-
------------
180-
* Insert
181-
- Insert multiple empty rows via prepared statements does not work in all cases
182-
183-
Development & Testing
184-
---------------------
185-
See `developer guide`_

doc/changes/changelog.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Changes
22

33
* [unreleased](unreleased.md)
4+
* [5.2.0](changes_5.2.0.md)
45
* [5.1.0](changes_5.1.0.md)
56
* [5.0.0](changes_5.0.0.md)
67
* [4.6.3](changes_4.6.3.md)
@@ -63,6 +64,7 @@
6364
hidden:
6465
---
6566
unreleased
67+
changes_5.2.0
6668
changes_5.1.0
6769
changes_5.0.0
6870
changes_4.6.3
@@ -120,4 +122,3 @@ changes_0.7.5
120122
changes_0.7.4
121123
changes_0.7.0
122124
```
123-

doc/changes/changes_5.2.0.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# 5.2.0 - 2025-11-04
2+
3+
This release drops the support for Python 3.9 as this Python version has reached its [end-of-life](https://devguide.python.org/versions/) in 2025-10. In consequence, the release also fixes security vulnerabilities by updating the dependencies.
4+
5+
With this release, in the Websocket-based dialect, it is possible for users to pass `FINGERPRINT` into
6+
the connection URL to take advantage of an additional security feature in PyExasol version
7+
1.x.
8+
9+
```python
10+
from sqlalchemy import create_engine
11+
url = "exa+websocket://A_USER:[email protected]:1234/my_schema?FINGERPRINT=C70EB4DC0F62A3BF8FD7FF22D2EB2C489834958212AC12C867459AB86BE3A028"
12+
engine = create_engine(url)
13+
query = "select 42 from dual"
14+
with engine.connect() as con:
15+
result = con.execute(sql.text(query)).fetchall()
16+
```
17+
18+
## Feature
19+
20+
- #612: Updated CI tests to run against Exasol DB versions 7.1.30, 8.34.0, and 2025.1.0. Dropped support for Python 3.9.
21+
- #637: Added option to `exa-websocket` (Websocket-based dialect) to pass `FINGERPRINT` in the connection URL for additional security
22+
23+
## Refactoring
24+
25+
- #610: Altered string input into `Connection.execute()` to be handled properly with `sql.text()`
26+
- #614: Altered params input into `Connection.execute()` to be handled properly with `dict`
27+
- #616: Altered usage of MetaData which was binding to a connection to instead bind in the needed object or function
28+
- #617: Enacted warning for the deprecation of the `autoload` parameter and requirement of `bind`
29+
- #618: Switched DML & DDL executions from `engine.connect()` to `engine.begin()` usage
30+
- #637: Updated dependency declaration to `pyexasol`
31+
32+
## Internal
33+
34+
- #558: Updated to poetry 2.1.2 & relocked dependencies to resolve CVE-2025-27516
35+
- #548: Replaced pytest-exasol-itde with pytest-backend
36+
- Relocked dependencies to resolve CVE-2025-43859
37+
- #564: Replaced nox test:unit with that from exasol-toolbox
38+
- Reformatted files to meet project specifications
39+
- #588: Updated to exasol-toolbox 1.6.0 and relocked dependencies to resolve CVE-2025-50182, CVE-2025-50181, & CVE-2024-47081
40+
- #605: Removed non-ASCII unicode from templates & relocked dependencies to resolve CVE-2025-8869 (pip -> transitive dependency)
41+
- #640: Re-locked dependencies to resolve CVE-2025-8869 for transitive dependency pip
42+
43+
## Dependency Updates
44+
45+
### `main`
46+
* Updated dependency `packaging:24.2` to `25.0`
47+
* Updated dependency `pyexasol:0.27.0` to `1.2.1`
48+
* Updated dependency `pyodbc:5.2.0` to `5.3.0`
49+
50+
### `dev`
51+
* Removed dependency `black:25.1.0`
52+
* Updated dependency `exasol-integration-test-docker-environment:3.4.0` to `4.3.0`
53+
* Updated dependency `exasol-toolbox:0.20.0` to `1.12.0`
54+
* Removed dependency `furo:2024.8.6`
55+
* Removed dependency `isort:5.13.2`
56+
* Removed dependency `mypy:1.15.0`
57+
* Updated dependency `nox:2025.2.9` to `2025.10.16`
58+
* Removed dependency `pre-commit:4.1.0`
59+
* Removed dependency `pylint:3.3.4`
60+
* Updated dependency `pyodbc:5.2.0` to `5.3.0`
61+
* Removed dependency `pytest-cov:6.0.0`
62+
* Added dependency `pytest-exasol-backend:1.2.2`
63+
* Removed dependency `pytest-exasol-itde:0.2.1`
64+
* Removed dependency `pytest-history:0.3.0`
65+
* Removed dependency `pyupgrade:3.19.1`
66+
* Removed dependency `sphinx:7.4.7`
67+
* Removed dependency `sphinx-copybutton:0.5.2`
68+
* Removed dependency `urlscan:1.0.6`

doc/changes/unreleased.md

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1 @@
11
# Unreleased
2-
3-
Due to an EOL for [Python 3.9 in 2025-10](https://devguide.python.org/versions/), we dropped support for it.
4-
This allows us to use the latest dependencies, which do not have open vulnerabilities.
5-
6-
## Feature
7-
8-
- #612: Updated CI tests to run against Exasol DB versions 7.1.30, 8.34.0, and 2025.1.0. Dropped support for Python 3.9.
9-
10-
## Refactoring
11-
12-
- #610: Altered string input into `Connection.execute()` to be handled properly with `sql.text()`
13-
- #614: Altered params input into `Connection.execute()` to be handled properly with `dict`
14-
- #616: Altered usage of MetaData which was binding to a connection to instead bind in the needed object or function
15-
- #617: Enacted warning for the deprecation of the `autoload` parameter and requirement of `bind`
16-
- #618: Switched DML & DDL executions from `engine.connect()` to `engine.begin()` usage
17-
18-
## Internal
19-
20-
- #558: Updated to poetry 2.1.2 & relocked dependencies to resolve CVE-2025-27516
21-
- #548: Replaced pytest-exasol-itde with pytest-backend
22-
- Relocked dependencies to resolve CVE-2025-43859
23-
- #564: Replaced nox test:unit with that from exasol-toolbox
24-
- Reformatted files to meet project specifications
25-
- #588: Updated to exasol-toolbox 1.6.0 and relocked dependencies to resolve CVE-2025-50182, CVE-2025-50181, & CVE-2024-47081
26-
- #605: Removed non-ASCII unicode from templates & relocked dependencies to resolve CVE-2025-8869 (pip -> transitive dependency)
27-
- #640: Re-locked dependencies to resolve CVE-2025-8869 for transitive dependency pip

0 commit comments

Comments
 (0)