Skip to content

Commit c032ded

Browse files
authored
Refactoring/404 drop pyodbc support (#649)
* Remove pyodbc and odbc comments from documents * Remove pyodbc from code part 1 * Make comment general after removing pyodbc * Remove skip related to pyodbc; as tests should be ok to run now * Remove override due to pyodbc * Remove EXAODBC from connection string for websocket * Add to documentation per: Implicit autocommit was removed in SQLAlchemy 2.0. Use the .begin() method of Engine or Connection in order to use an explicit transaction for DML and DDL statements. (Background on SQLAlchemy 2.0 at: https://sqlalche.me/e/b8d9) * Modify regression test to websocket, the remaining dialect variant * Drop support for pyodbc with changelog entry * With 2.0, we do not need the plugin * Add typing hint for colspec to resolve base.py mypy error * Remove older comment as not restricted anymore to pytest <6 * Remove odbc installation instructions for Ubuntu and ODBC usage * Switch to websocket, as last remaining dialect * Remove ODBC skip as no longer relevant; restore default test as override not needed; mark added test * With pyodbc removal, linting dropped to 4.9. Should create ticket to bring back up * Update slow tests to separately run sqla, exasol, & regression tests to make debugging easier in future * Fix test to reduced state with only websocket still * Without ODBC dialects, there is no longer a use_sql_fallback argument. Thus, test_compare_get_schema_names_for_sql_and_odbc is obsolete, as covered by test_get_schema_names * Without ODBC dialects, there is no longer a use_sql_fallback argument. Thus, test_compare_get_table_names_for_sql_and_odbc is obsolete, as covered by test_get_table_names * Without ODBC dialects, there is no longer a use_sql_fallback argument. Thus, test_has_table_table_exists and test_has_table_table_exists_not can be simplified and test_compare_has_table_for_sql_and_odbc can be removed. * Without ODBC dialects, there is no longer a use_sql_fallback argument. Thus, these tests can be simplified * Without ODBC dialects, there is no longer a use_sql_fallback argument. Thus, these tests can be removed for test_get_view_names and test_get_view_definition already cover * Without ODBC dialects, there is no longer a use_sql_fallback argument. Thus, these tests can be simplified. * Without ODBC dialects, there is no longer a use_sql_fallback argument. Thus, these tests can be dropped as covered by test_get_columns, test_get_foreign_keys, test_get_pk_constraint * Remove comment with ODBC mention * Reduce tests as sql_fallback does not exist now that ODBC-based dialects are gone * Switch from skip in requirements.py to xfail in the tests * Start collecting recurring issues in XfailRationale class - Switch to Xfail with strict=True so that changes in state are obvious, i.e. failed test suite - Stop overriding DifficultParametersTest as found all tests pass now * Collect more recurring issues in XfailRationale class - Switch from EXPLICIT_INDEX to MANUAL_INDEX - ExpandingBoundInTest.test_null_in_empty_set_is_false is not a valid test anymore; this highlights the importance of using super() and XFAIL * Finish moving skips to xfails * Re-add test with modifications as only 1 still fails for <= 7.1.30 * Turn off autocommit in the connection for rollback to work * Add change to README.rst per review comment * Add changes to test_suite.py per review comments * Add change to unreleased.md per review comment * Add change to developer_guide.rst per review comment * Add change to user_guide.rst per review comment * Move user_guide into its own directory as will expand in future and rename
1 parent 39e59cd commit c032ded

33 files changed

+238
-1451
lines changed

.github/workflows/slow-checks.yml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
contents: read
1212

1313
tests:
14-
name: Integration-Tests (${{matrix.connector}}, Python-${{ matrix.python-version }}, Exasol-${{ matrix.exasol-version}})
14+
name: Integration-Tests (Python-${{ matrix.python-version }}, test:${{ matrix.integration-group }}, Exasol-${{ matrix.exasol-version}}, ${{matrix.connector}})
1515
needs: [ build-matrix ]
1616
runs-on: ubuntu-24.04
1717
permissions:
@@ -31,17 +31,20 @@ jobs:
3131
with:
3232
python-version: ${{ matrix.python-version }}
3333

34-
- name: Install via apt
35-
run: sudo apt-get install unixodbc unixodbc-dev libboost-date-time-dev libboost-locale-dev libboost-system-dev
34+
- name: Start test db
35+
run: poetry run -- nox -s db:start -- --db-version ${{ matrix.exasol-version }}
3636

3737
- name: Run Tests and Collect Coverage
3838
run: |
3939
export SQLALCHEMY_WARN_20=1
40-
poetry run -- nox -s test:integration -- --coverage --db-version ${{ matrix.exasol-version }}
40+
poetry run -- nox -s test:${{ matrix.integration-group }}
4141
4242
- name: Upload Artifacts
4343
uses: actions/upload-artifact@v5
4444
with:
45-
name: coverage-python${{ matrix.python-version }}-${{matrix.connector}}-exasol${{ matrix.exasol-version }}slow
45+
name: coverage-python${{ matrix.python-version }}-${{ matrix.integration-group }}-exasol${{ matrix.exasol-version }}-${{matrix.connector}}-slow
4646
path: .coverage
4747
include-hidden-files: true
48+
49+
- name: Stop test db
50+
run: poetry run -- nox -s db:stop

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
.lint*
22
.test-results.db
33
.html-documentation
4-
odbcconfig/odbcinst.ini
54

65
_build/
76

README.rst

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -42,32 +42,15 @@ SQLAlchemy Dialect for EXASOL DB
4242
:target: https://pypi.org/project/sqlalchemy_exasol
4343
:alt: PyPI - Downloads
4444

45-
4645
Getting Started with SQLAlchemy-Exasol
4746
--------------------------------------
48-
SQLAlchemy-Exasol supports multiple dialects, primarily differentiated by whether they are ODBC or Websocket-based.
49-
50-
Choosing a Dialect
51-
++++++++++++++++++
52-
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.
55-
56-
.. warning::
57-
58-
The maintenance of pyodbc support is currently paused, and it is planned to be phased out in future versions.
59-
47+
SQLAlchemy-Exasol supports a Websocket-based dialect.
6048

6149
System Requirements
6250
-------------------
63-
- Exasol >= 7.1 (e.g. `docker-db <test_docker_image_>`_ or a `cloud instance <test_drive_>`_)
51+
- Exasol >= 7.1 (e.g. `docker-db <test_docker_image_>`_ or a `Exasol SaaS instance <test_drive_>`_)
6452
- Python >= 3.10
6553

66-
.. note::
67-
68-
For ODBC-Based Dialects, additional libraries required for ODBC are necessary
69-
(for further details, checkout the `developer guide`_).
70-
7154
Features
7255
--------
7356

@@ -80,5 +63,4 @@ Check out sqlalchemy-exasols's [User Guide(https://exasol.github.io/sqlalchemy-e
8063

8164
.. _developer guide: https://github.com/exasol/sqlalchemy-exasol/blob/master/doc/developer_guide/developer_guide.rst
8265
.. _test_docker_image: https://github.com/exasol/docker-db
83-
.. _odbc_driver: https://docs.exasol.com/db/latest/connect_exasol/drivers/odbc/odbc_linux.htm
8466
.. _test_drive: https://cloud.exasol.com/signup

doc/changes/unreleased.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Unreleased
22

3-
In this release, the ODBC-dialect Turbodbc was dropped.
3+
In this release, the ODBC-based dialects pyodbc and Turbodbc were dropped. Please
4+
switch over to using the websocket dialect. Connection
5+
strings should be altered to start with `exa+websocket://`.
46

57
## Refactoring
68

@@ -17,3 +19,4 @@ In this release, the ODBC-dialect Turbodbc was dropped.
1719
- `ReturningGuardsTest` are used to indicate that the Exasol dialect, which does not natively support the [RETURNING clause](https://docs.sqlalchemy.org/en/20/glossary.html#term-RETURNING), is set up per the API specifications
1820
- `ComponentReflectionTest.test_not_existing_table` is used to indicate that specific `EXADialect` methods (i.e. `get_columns`) check to see if the requested table/view exists and if not, they will now toss a `NoSuchTableError` exception
1921
- #403: Dropped support for Turbodbc
22+
- #404: Dropped support for pyodbc

doc/developer_guide/developer_guide.rst

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,9 @@ Tools
1818
* Prerequisites_
1919

2020

21-
Libraries
22-
+++++++++
23-
* unixodbc
24-
* unixodbc-dev
25-
* libboost-date-time-dev
26-
* libboost-locale-dev
27-
* libboost-system-dev
28-
29-
30-
Example: Install of required system libraries on Ubuntu
31-
32-
.. code-block::
33-
34-
sudo apt-get install unixodbc unixodbc-dev libboost-date-time-dev libboost-locale-dev libboost-system-dev
35-
36-
3721
Locale
3822
+++++++
39-
Make sure the local is setup appropriately.
23+
Make sure the locale is set up appropriately.
4024

4125
Example: Setting up an english locale
4226

@@ -125,23 +109,10 @@ Tests
125109

126110
.. code-block::
127111
128-
# make sure you are using the virtual environment poetry has setup for this project
112+
# make sure you are using the virtual environment poetry has set up for this project
129113
poetry shell
130114
131115
132-
#. Run all tests with `pyodbc` connector
133-
134-
.. code-block::
135-
136-
nox
137-
138-
or
139-
140-
.. code-block::
141-
142-
nox -s "verify(connector='pyodbc')"
143-
144-
145116
.. attention::
146117

147118
If something still is not working or unclear, you may want to look into the CI/CD action_ files.

doc/index.rst

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,13 @@ Documentation of SQLAlchemy-Exasol
2222
:link: faq
2323
:link-type: ref
2424

25-
Frequently asked questsions.
25+
Frequently asked questions.
2626

2727
.. toctree::
2828
:maxdepth: 1
2929
:hidden:
3030

31-
user_guide
31+
user_guide/index
3232
developer_guide/index
3333
faq
3434
changes/changelog
35-

doc/user_guide.rst renamed to doc/user_guide/index.rst

Lines changed: 7 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -46,28 +46,20 @@ Getting Started
4646
# sqlalchemy 2.x, be passed through `sqlalchemy.sql.text`.
4747
result = con.execute(sql.text("select 42 from dual")).fetchall()
4848
49-
# engine.begin() is for DML & DDL, as we don't want to rely on autocommit
50-
# but you can with `engine.connect()` commit as you go with `con.commit()`
49+
# For easier usage of transactions, you can use engine.begin() for DML & DDL,
50+
# if you don't want to rely on autocommit. However, you can with
51+
# `engine.connect()` commit as you go with `con.commit()` or use, for more
52+
# complex scenarios:
53+
# with engine.connect() as con:
54+
# with conn.begin():
55+
# ...
5156
with engine.begin() as con:
5257
...
5358
5459
55-
.. warning::
56-
57-
To use an ODBC-based dialect, you must specify it as an extra during installation.
58-
Maintenance for these ODBC-based dialects is paused, and it is planned to remove them
59-
in future versions.
60-
61-
.. code-block:: shell
62-
63-
pip install "sqlalchemy-exasol[pydobc]"
64-
6560
Further Examples
6661
~~~~~~~~~~~~~~~~
6762

68-
Websocket-based Dialect
69-
------------------------
70-
7163
.. code-block:: python
7264
7365
from sqlalchemy import create_engine, sql
@@ -116,30 +108,6 @@ Websocket-based Dialect
116108
...
117109
118110
119-
.. note::
120-
Validation with fingerprint is only supported in the Websocket-based dialect, and not
121-
the ODBC-based dialect (Pyodbc).
122-
123-
124-
Pyodbc-based Dialect
125-
---------------------
126-
127-
.. code-block:: python
128-
129-
from sqlalchemy import create_engine, sql
130-
131-
user = "sys"
132-
password = "exasol"
133-
host = "127.0.0.1"
134-
port = "8563
135-
schema = "my_schema
136-
137-
url = f"exa+pyodbc://{user}:{password}@{host}:{port}/{schema}?CONNECTIONLCALL=en_US.UTF-8&driver=EXAODBC"
138-
engine = create_engine(url)
139-
query = "select 42 from dual"
140-
with engine.connect() as con:
141-
result = con.execute(sql.text(query)).fetchall()
142-
143111
General Notes
144112
~~~~~~~~~~~~~
145113

driver/libexaodbc-uo2214lv2.so

-7.9 MB
Binary file not shown.

exasol/odbc.py

Lines changed: 0 additions & 67 deletions
This file was deleted.

noxconfig.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class Config(BaseConfig):
5151
environment_name: str = "test"
5252
db_port: int = 8563
5353
bucketfs_port: int = 2580
54-
connectors: list[str] = ["pyodbc", "websocket"]
54+
connectors: list[str] = ["websocket"]
5555
plugins: list = [StartDB, StopDB]
5656

5757

0 commit comments

Comments
 (0)