Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,8 @@ ENV/
# PyCharm project settings
.idea
.idea/

.venv/
.pytest_cache/
.mypy_cache/

12 changes: 7 additions & 5 deletions ACKNOWLEDGMENTS
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
THIS PROJECT IS DERIVED FROM THE FOLLOWING PROJECTS/FORKS:
- https://github.com/LocusEnergy/sqlalchemy-vertica-python
THIS PROJECT IS THE MAINLY DERIVED FROM startappdev repo:
- https://github.com/startappdev/sqlalchemy-vertica

THIS PROJECT WAS ALSO DERIVED FROM THE FOLLOWING PROJECTS:

- https://github.com/zzzeek/sqlalchemy
- https://github.com/bluelabsio/vertica-sqlalchemy
- https://github.com/dennisobrien/sqlalchemy-vertica-python
- https://github.com/Eighty20/sqlalchemy-vertica-python

THANKS TO ALL THE GREAT PEOPLE WHO'VE CONTRIBUTED TO THESE PROJECTS.
- https://github.com/LocusEnergy/sqlalchemy-vertica-python
- https://github.com/dennisobrien/sqlalchemy-vertica-python
211 changes: 192 additions & 19 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,35 +1,208 @@
sqlalchemy-vertica
==================

Vertica dialect for sqlalchemy.
Modern **Vertica Analytic Database** dialect for **SQLAlchemy 2.0+** with full support for **Async operations**, **Alembic migrations**, and modern Python (3.9 - 3.14+).

Forked from the `Vertica dialect for sqlalchemy using vertica-python <https://pypi.python
.org/pypi/sqlalchemy-vertica-python>`_.
.. image:: https://img.shields.io/badge/SQLAlchemy-2.0+-blue.svg
:target: https://www.sqlalchemy.org/
.. image:: https://img.shields.io/badge/python-3.9+-blue.svg
:target: https://www.python.org/
.. image:: https://img.shields.io/badge/Vertica-11--24+-green.svg
:target: https://www.vertica.com/
.. image:: https://img.shields.io/badge/license-MIT-green.svg
:target: https://opensource.org/licenses/MIT

.. code-block:: python

import sqlalchemy as sa
import urllib
# for pyodbc connection
sa.create_engine('vertica+pyodbc:///?odbc_connect=%s' % (urllib.quote('DSN=dsn'),))
Features
--------

# for turbodbc connection
sa.create_engine('vertica+turbodbc:///?DSN=dsn')
* **Full SQLAlchemy 2.0+ Architecture**: Built on ``DefaultDialect`` with query caching (``supports_statement_cache = True``), 2.0 execution semantics, and parameter-bound reflection.
* **First-Class Async Engine Support**: Run queries asynchronously with ``create_async_engine()`` and ``AsyncSession`` via ``vertica+vertica_python_async://`` without blocking the asyncio event loop.
* **Alembic Migrations**: Native ``VerticaImpl`` integration with transactional DDL, type synonym resolution, and index no-op handling (since Vertica utilizes projections).
* **Multi-Driver Support**:
* ``vertica-python`` (Synchronous pure-Python DBAPI driver)
* ``vertica-python-async`` (Asynchronous DBAPI adapter for non-blocking asyncio / FastAPI apps)
* ``pyodbc`` (ODBC driver)
* ``turbodbc`` (High-speed ODBC driver for Arrow / NumPy / Pandas data workflows)
* **Rich Vertica Data Types**:
* Geospatial: ``GEOMETRY``, ``GEOGRAPHY``
* Identifiers: native ``UUID``
* Large objects: ``LONG VARCHAR``, ``LONG VARBINARY`` (up to 32MB)
* Complex types: ``ARRAY``, ``MAP``, ``ROW`` (Vertica 10+)
* Temporal: ``TIMESTAMPTZ``, ``TIMETZ``, ``INTERVAL``
* **Complete Reflection**: Automatic introspection of schemas, tables, temp tables, views, view definitions, columns, primary keys, foreign keys, unique constraints, check constraints, table & column comments.

# for vertica-python connection
sa.create_engine('vertica+vertica_python://user:pwd@host:port/database')

Installation
------------

From PyPI: ::
Install from PyPI with your desired driver extras:

.. code-block:: bash

# Pure Python sync driver (recommended for sync applications)
pip install "sqlalchemy-vertica[vertica-python]"

# Pure Python async driver (for AsyncEngine / FastAPI / asyncio)
pip install "sqlalchemy-vertica[asyncio]"

# ODBC drivers
pip install "sqlalchemy-vertica[pyodbc]"
pip install "sqlalchemy-vertica[turbodbc]"

# Alembic migrations support
pip install "sqlalchemy-vertica[alembic]"

# Install all drivers and tools
pip install "sqlalchemy-vertica[all]"


Connection Strings
------------------

.. code-block:: python

import sqlalchemy as sa
from sqlalchemy.ext.asyncio import create_async_engine

# 1. Async (for FastAPI / asyncio applications)
async_engine = create_async_engine(
"vertica+vertica_python_async://user:pwd@host:5433/database?connection_timeout=10"
)

# 2. Sync vertica-python
engine = sa.create_engine(
"vertica+vertica_python://user:pwd@host:5433/database?connection_timeout=10"
)

# 3. PyODBC with connection string
engine_pyodbc = sa.create_engine(
"vertica+pyodbc:///?odbc_connect=DSN%3DVerticaDSN"
)

# 4. Turbodbc with DSN
engine_turbodbc = sa.create_engine(
"vertica+turbodbc:///?DSN=VerticaDSN"
)


Quick Start
-----------

Synchronous SQLAlchemy 2.0
^^^^^^^^^^^^^^^^^^^^^^^^^^

.. code-block:: python

from sqlalchemy import create_engine, text

engine = create_engine("vertica+vertica_python://user:pwd@localhost:5433/mydb")

with engine.connect() as conn:
result = conn.execute(text("SELECT version()"))
print(result.scalar())

# Transaction block
with engine.begin() as conn:
conn.execute(
text("INSERT INTO my_table (name) VALUES (:name)"),
{"name": "Alice"}
)


Asynchronous SQLAlchemy 2.0 & FastAPI
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. code-block:: python

import asyncio
from sqlalchemy import text
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker

async def main():
engine = create_async_engine(
"vertica+vertica_python_async://user:pwd@localhost:5433/mydb",
pool_size=10,
)

async with engine.connect() as conn:
result = await conn.execute(text("SELECT 1"))
print(result.scalar())

# Using AsyncSession
session_factory = async_sessionmaker(engine, class_=AsyncSession)
async with session_factory() as session:
result = await session.execute(text("SELECT COUNT(*) FROM my_table"))
print("Count:", result.scalar())

await engine.dispose()

asyncio.run(main())


Alembic Migrations
------------------

In your Alembic ``env.py``, simply import ``sqlalchemy_vertica``:

.. code-block:: python

import sqlalchemy_vertica # Registers VerticaImpl plugin automatically
from alembic import context

# configure context
context.configure(
connection=connection,
target_metadata=target_metadata,
transactional_ddl=True,
)

Vertica does not support traditional B-tree indexes (it utilizes projections). ``sqlalchemy-vertica`` treats index creation/dropping as safe no-ops in migrations to ensure multi-database migration scripts run seamlessly.


Custom Data Types
-----------------

.. code-block:: python

from sqlalchemy import Column, Integer, Table, MetaData
from sqlalchemy_vertica import (
GEOMETRY,
GEOGRAPHY,
UUID,
LONG_VARCHAR,
ARRAY,
MAP,
ROW,
TIMESTAMPTZ,
)

metadata = MetaData()

places = Table(
"places",
metadata,
Column("id", Integer, primary_key=True, autoincrement=True),
Column("guid", UUID, nullable=False),
Column("description", LONG_VARCHAR),
Column("location", GEOMETRY(srid=4326)),
Column("tags", ARRAY(LONG_VARCHAR)),
Column("metadata", MAP(LONG_VARCHAR, LONG_VARCHAR)),
Column("created_at", TIMESTAMPTZ),
)


Testing & Coverage
------------------

Run the automated test suite with ``pytest`` and ``pytest-cov``:

.. code-block:: bash

pip install sqlalchemy-vertica[pyodbc,turbodbc,vertica-python] # choose the relevant engines
pytest -v --cov=sqlalchemy_vertica --cov-report=term-missing

From git: ::

git clone https://github.com/startappdev/sqlalchemy-vertica
cd sqlalchemy-vertica
pip install pyodbc turbodbc vertica-python # choose the relevant engines
python setup.py install
License
-------

MIT License. See `LICENSE` for details.
106 changes: 106 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"

[project]
name = "sqlalchemy-vertica"
version = "1.0.0"
description = "Vertica dialect for SQLAlchemy 2.0+ with Async & Alembic support"
readme = "README.rst"
license = "MIT"
authors = [
{name = "Luis Villamarin", email = "luis@lv10.me"}
]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Topic :: Database",
"Topic :: Database :: Front-Ends",
]
requires-python = ">=3.9"
dependencies = [
"sqlalchemy>=2.0.0",
"typing_extensions>=4.6.0",
]

[project.optional-dependencies]
vertica-python = [
"vertica-python>=1.0.0",
]
asyncio = [
"vertica-python>=1.0.0",
"greenlet>=3.0.0",
]
pyodbc = [
"pyodbc>=4.0.35",
]
turbodbc = [
"turbodbc>=4.0.0",
]
alembic = [
"alembic>=1.11.0",
]
all = [
"vertica-python>=1.0.0",
"greenlet>=3.0.0",
"pyodbc>=4.0.35",
"turbodbc>=4.0.0",
"alembic>=1.11.0",
]
dev = [
"pytest>=7.4.0",
"pytest-asyncio>=0.21.0",
"pytest-cov>=4.1.0",
"coverage[toml]>=7.3.0",
"mypy>=1.5.0",
"flake8>=6.0.0",
]

[project.urls]
Homepage = "https://github.com/lv10/sqlalchemy-vertica"
Repository = "https://github.com/lv10/sqlalchemy-vertica"

[project.entry-points."sqlalchemy.dialects"]
vertica = "sqlalchemy_vertica.dialect_vertica_python:VerticaDialect"
"vertica.vertica_python" = "sqlalchemy_vertica.dialect_vertica_python:VerticaDialect"
"vertica.vertica_python_async" = "sqlalchemy_vertica.dialect_vertica_python_async:VerticaDialect_vertica_python_async"
"vertica.async_vertica_python" = "sqlalchemy_vertica.dialect_vertica_python_async:VerticaDialect_vertica_python_async"
"vertica.pyodbc" = "sqlalchemy_vertica.dialect_pyodbc:VerticaDialect"
"vertica.turbodbc" = "sqlalchemy_vertica.dialect_turbodbc:VerticaDialect"

[tool.setuptools.packages.find]
where = ["."]
include = ["sqlalchemy_vertica*"]

[tool.pytest.ini_options]
minversion = "7.0"
addopts = "-ra --cov=sqlalchemy_vertica --cov-report=term-missing"
testpaths = ["tests"]
asyncio_mode = "auto"

[tool.coverage.run]
source = ["sqlalchemy_vertica"]
branch = true

[tool.coverage.report]
show_missing = true
skip_covered = false
exclude_lines = [
"pragma: no cover",
"def __repr__",
"if TYPE_CHECKING:",
"raise NotImplementedError",
"\\.\\.\\.",
]

[tool.mypy]
python_version = "3.12"
warn_unused_configs = true
ignore_missing_imports = true
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
six >= 1.10.0
sqlalchemy >= 1.1.5
sqlalchemy>=2.0.0
typing_extensions>=4.6.0
2 changes: 0 additions & 2 deletions setup.cfg

This file was deleted.

Loading