SQLAlchemy 2.0 dialect for the CUBRID database — Python ORM, schema reflection, Alembic migrations, and full type system support.
🇰🇷 한국어 · 🇺🇸 English · 🇨🇳 中文 · 🇮🇳 हिन्दी · 🇩🇪 Deutsch · 🇷🇺 Русский
CUBRID is a high-performance open-source relational database, widely adopted in Korean public-sector and enterprise applications. Until now, there was no production-ready SQLAlchemy dialect that supports the modern 2.0 API.
sqlalchemy-cubrid bridges that gap:
- Full SQLAlchemy 2.0 dialect with statement caching and PEP 561 typing
- 426 offline tests with 99%+ code coverage — no database required to run them
- Tested against 4 CUBRID versions (10.2, 11.0, 11.2, 11.4) across Python 3.10 -- 3.13
- CUBRID-specific DML constructs:
ON DUPLICATE KEY UPDATE,MERGE,REPLACE INTO - Alembic migration support out of the box
- Two driver options — C-extension (
cubrid://) or pure Python (cubrid+pycubrid://)
flowchart TD
app["Application"] --> sa["SQLAlchemy Core/ORM"]
sa --> dialect["CubridDialect"]
dialect --> pycubrid["pycubrid driver"]
dialect --> cext["CUBRIDdb driver"]
pycubrid --> server["CUBRID Server"]
cext --> server
flowchart TD
expr["SQL Expression"] --> compiler["CubridSQLCompiler"] --> sql["SQL String"]
- Python 3.10+
- SQLAlchemy 2.0 – 2.1
- CUBRID-Python (C-extension) or pycubrid (pure Python)
pip install sqlalchemy-cubridWith the pure Python driver (no C build needed):
pip install "sqlalchemy-cubrid[pycubrid]"With Alembic support:
pip install "sqlalchemy-cubrid[alembic]"from sqlalchemy import create_engine, text
engine = create_engine("cubrid://dba:password@localhost:33000/demodb")
with engine.connect() as conn:
result = conn.execute(text("SELECT 1"))
print(result.scalar())from sqlalchemy import create_engine, String
from sqlalchemy.orm import DeclarativeBase, Mapped, Session, mapped_column
class Base(DeclarativeBase):
pass
class User(Base):
__tablename__ = "users"
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
name: Mapped[str] = mapped_column(String(100))
email: Mapped[str] = mapped_column(String(200), unique=True)
engine = create_engine("cubrid://dba:password@localhost:33000/demodb")
Base.metadata.create_all(engine)
with Session(engine) as session:
user = User(name="Alice", email="alice@example.com")
session.add(user)
session.commit()- Complete type system -- numeric, string, date/time, bit, LOB, and collection types
- SQL compilation -- SELECT, JOIN, CAST, LIMIT/OFFSET, subqueries, CTEs, window functions
- DML extensions --
ON DUPLICATE KEY UPDATE,MERGE,REPLACE INTO,FOR UPDATE,TRUNCATE - DDL support --
COMMENT,IF NOT EXISTS/IF EXISTS,AUTO_INCREMENT - Schema reflection -- tables, views, columns, PKs, FKs, indexes, unique constraints, comments
- Alembic migrations via
CubridImpl(auto-discovered entry point) - All 6 CUBRID isolation levels (dual-granularity: class-level + instance-level)
| Guide | Description |
|---|---|
| Connection | Connection strings, URL format, driver setup, pool tuning |
| Type Mapping | Full type mapping, CUBRID-specific types, collection types |
| DML Extensions | ON DUPLICATE KEY UPDATE, MERGE, REPLACE INTO, query trace |
| Isolation Levels | All 6 CUBRID isolation levels, configuration |
| Alembic Migrations | Setup, configuration, limitations, batch workarounds |
| Feature Support | Comparison with MySQL, PostgreSQL, SQLite |
| ORM Cookbook | Practical ORM examples, relationships, queries |
| Development | Dev setup, testing, Docker, coverage, CI/CD |
| Driver Compatibility | CUBRID-Python driver versions and known issues |
| Troubleshooting | Common issues, error solutions, debugging techniques |
| Python 3.10 | Python 3.11 | Python 3.12 | Python 3.13 | |
|---|---|---|---|---|
| Offline Tests | ✅ | ✅ | ✅ | ✅ |
| CUBRID 11.4 | ✅ | -- | ✅ | -- |
| CUBRID 11.2 | ✅ | -- | ✅ | -- |
| CUBRID 11.0 | ✅ | -- | ✅ | -- |
| CUBRID 10.2 | ✅ | -- | ✅ | -- |
from sqlalchemy import create_engine
engine = create_engine("cubrid://dba:password@localhost:33000/demodb")For the pure Python driver (no C build needed): create_engine("cubrid+pycubrid://dba@localhost:33000/demodb")
Yes. sqlalchemy-cubrid is built for SQLAlchemy 2.0+ and supports the new 2.0-style API including Session.execute(), typed Mapped[] columns, and statement caching.
Yes. Install with pip install "sqlalchemy-cubrid[alembic]". The dialect auto-registers via entry point. Note that CUBRID auto-commits DDL, so migrations are not transactional.
Python 3.10, 3.11, 3.12, and 3.13.
No. CUBRID does not support INSERT ... RETURNING or UPDATE ... RETURNING. Use cursor.lastrowid or SELECT LAST_INSERT_ID() instead.
from sqlalchemy_cubrid import insert
stmt = insert(users).values(name="Alice").on_duplicate_key_update(name="Alice Updated")cubrid:// uses the C-extension driver (CUBRIDdb) which requires compilation. cubrid+pycubrid:// uses the pure Python driver which installs with pip alone — no build tools needed.
- pycubrid — Pure Python DB-API 2.0 driver for CUBRID
- cubrid-python-cookbook — Production-ready Python examples for CUBRID
See ROADMAP.md for this project's direction and next milestones.
For the ecosystem-wide view, see the CUBRID Labs Ecosystem Roadmap and Project Board.
See CONTRIBUTING.md for guidelines and docs/DEVELOPMENT.md for development setup.
Report vulnerabilities via email -- see SECURITY.md. Do not open public issues for security concerns.
MIT -- see LICENSE.