sqlalchemy-cubrid 1.2.1__tar.gz → 1.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. sqlalchemy_cubrid-1.2.2/PKG-INFO +113 -0
  2. sqlalchemy_cubrid-1.2.2/README.md +79 -0
  3. {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/pyproject.toml +8 -50
  4. {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/sqlalchemy_cubrid/__init__.py +2 -15
  5. sqlalchemy_cubrid-1.2.2/sqlalchemy_cubrid/alembic_impl.py +69 -0
  6. {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/sqlalchemy_cubrid/base.py +14 -16
  7. {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/sqlalchemy_cubrid/compiler.py +58 -140
  8. {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/sqlalchemy_cubrid/dialect.py +74 -295
  9. {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/sqlalchemy_cubrid/dml.py +6 -57
  10. sqlalchemy_cubrid-1.2.2/sqlalchemy_cubrid/requirements.py +270 -0
  11. {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/sqlalchemy_cubrid/types.py +30 -156
  12. sqlalchemy_cubrid-1.2.2/sqlalchemy_cubrid.egg-info/PKG-INFO +113 -0
  13. {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/sqlalchemy_cubrid.egg-info/SOURCES.txt +0 -8
  14. {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/sqlalchemy_cubrid.egg-info/entry_points.txt +0 -2
  15. sqlalchemy_cubrid-1.2.2/sqlalchemy_cubrid.egg-info/requires.txt +11 -0
  16. sqlalchemy_cubrid-1.2.2/test/test_alembic.py +120 -0
  17. {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/test/test_compiler.py +1 -175
  18. {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/test/test_dialect_offline.py +20 -314
  19. {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/test/test_dialects.py +0 -30
  20. sqlalchemy_cubrid-1.2.2/test/test_integration.py +326 -0
  21. {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/test/test_types.py +0 -16
  22. sqlalchemy_cubrid-1.2.1/PKG-INFO +0 -281
  23. sqlalchemy_cubrid-1.2.1/README.md +0 -232
  24. sqlalchemy_cubrid-1.2.1/sqlalchemy_cubrid/aio_pycubrid_dialect.py +0 -130
  25. sqlalchemy_cubrid-1.2.1/sqlalchemy_cubrid/alembic_impl.py +0 -145
  26. sqlalchemy_cubrid-1.2.1/sqlalchemy_cubrid/pycubrid_dialect.py +0 -129
  27. sqlalchemy_cubrid-1.2.1/sqlalchemy_cubrid/requirements.py +0 -276
  28. sqlalchemy_cubrid-1.2.1/sqlalchemy_cubrid/trace.py +0 -92
  29. sqlalchemy_cubrid-1.2.1/sqlalchemy_cubrid.egg-info/PKG-INFO +0 -281
  30. sqlalchemy_cubrid-1.2.1/sqlalchemy_cubrid.egg-info/requires.txt +0 -20
  31. sqlalchemy_cubrid-1.2.1/test/test_aio_integration.py +0 -293
  32. sqlalchemy_cubrid-1.2.1/test/test_aio_pycubrid_dialect.py +0 -206
  33. sqlalchemy_cubrid-1.2.1/test/test_alembic.py +0 -261
  34. sqlalchemy_cubrid-1.2.1/test/test_integration.py +0 -613
  35. sqlalchemy_cubrid-1.2.1/test/test_json.py +0 -312
  36. sqlalchemy_cubrid-1.2.1/test/test_pycubrid_dialect.py +0 -306
  37. sqlalchemy_cubrid-1.2.1/test/test_trace.py +0 -197
  38. {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/AUTHORS +0 -0
  39. {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/LICENSE +0 -0
  40. {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/setup.cfg +0 -0
  41. {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/sqlalchemy_cubrid/py.typed +0 -0
  42. {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/sqlalchemy_cubrid.egg-info/dependency_links.txt +0 -0
  43. {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/sqlalchemy_cubrid.egg-info/top_level.txt +0 -0
  44. {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/test/test_base.py +0 -0
  45. {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/test/test_requirements.py +0 -0
  46. {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/test/test_suite.py +0 -0
@@ -0,0 +1,113 @@
1
+ Metadata-Version: 2.4
2
+ Name: sqlalchemy-cubrid
3
+ Version: 1.2.2
4
+ Summary: CUBRID dialect for SQLAlchemy
5
+ Author-email: Yeongseon Choe <yeongseon.choe@gmail.com>, Gyeongjun Paik <paikend@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/sqlalchemy-cubrid/sqlalchemy-cubrid
8
+ Project-URL: Repository, https://github.com/sqlalchemy-cubrid/sqlalchemy-cubrid
9
+ Project-URL: Documentation, https://github.com/sqlalchemy-cubrid/sqlalchemy-cubrid
10
+ Keywords: SQLAlchemy,CUBRID,dialect
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Requires-Python: >=3.10
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ License-File: AUTHORS
25
+ Requires-Dist: sqlalchemy<2.2,>=2.0
26
+ Provides-Extra: cubrid
27
+ Requires-Dist: CUBRID-Python; extra == "cubrid"
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest>=7.0; extra == "dev"
30
+ Requires-Dist: ruff>=0.4; extra == "dev"
31
+ Provides-Extra: alembic
32
+ Requires-Dist: alembic>=1.7; extra == "alembic"
33
+ Dynamic: license-file
34
+
35
+ # sqlalchemy-cubrid
36
+
37
+ CUBRID dialect for SQLAlchemy 2.0+.
38
+
39
+ [![CI](https://github.com/sqlalchemy-cubrid/sqlalchemy-cubrid/actions/workflows/ci.yml/badge.svg)](https://github.com/sqlalchemy-cubrid/sqlalchemy-cubrid/actions/workflows/ci.yml)
40
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/downloads/)
41
+ [![SQLAlchemy 2.0](https://img.shields.io/badge/SQLAlchemy-2.0-green.svg)](https://www.sqlalchemy.org/)
42
+ [![Coverage 99%](https://img.shields.io/badge/coverage-99%25-brightgreen.svg)](docs/DEVELOPMENT.md#code-coverage)
43
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
44
+
45
+ ## Requirements
46
+
47
+ - Python 3.10+
48
+ - SQLAlchemy 2.0 – 2.1
49
+ - [CUBRID-Python](https://github.com/CUBRID/cubrid-python) driver
50
+
51
+ ## Install
52
+
53
+ ```bash
54
+ pip install sqlalchemy-cubrid
55
+ ```
56
+
57
+ ## Quick Start
58
+
59
+ ```python
60
+ from sqlalchemy import create_engine, text
61
+
62
+ engine = create_engine("cubrid://dba:password@localhost:33000/demodb")
63
+
64
+ with engine.connect() as conn:
65
+ result = conn.execute(text("SELECT 1"))
66
+ print(result.scalar())
67
+ ```
68
+
69
+ ## Features
70
+
71
+ - Full SQLAlchemy 2.0 dialect with statement caching
72
+ - Complete type system — numeric, string, date/time, bit, LOB, and collection types
73
+ - SQL compilation — SELECT, JOIN, CAST, LIMIT/OFFSET, subqueries, CTEs, window functions
74
+ - DML extensions — `ON DUPLICATE KEY UPDATE`, `MERGE`, `FOR UPDATE`, `TRUNCATE`
75
+ - DDL support — `COMMENT`, `IF NOT EXISTS` / `IF EXISTS`, `AUTO_INCREMENT`
76
+ - Schema reflection — tables, views, columns, PKs, FKs, indexes, unique constraints, comments
77
+ - Alembic migrations via `CubridImpl` (auto-discovered entry point)
78
+ - All 6 CUBRID isolation levels
79
+ - PEP 561 typed package
80
+
81
+ ## Documentation
82
+
83
+ | Guide | Description |
84
+ |---|---|
85
+ | **[Connection](docs/CONNECTION.md)** | Connection strings, URL format, driver setup, troubleshooting |
86
+ | **[Type Mapping](docs/TYPES.md)** | Full type mapping, CUBRID-specific types, collection types |
87
+ | **[DML Extensions](docs/DML_EXTENSIONS.md)** | ON DUPLICATE KEY UPDATE, MERGE, GROUP_CONCAT, TRUNCATE, index hints |
88
+ | **[Isolation Levels](docs/ISOLATION_LEVELS.md)** | All 6 CUBRID isolation levels, configuration, comparison |
89
+ | **[Alembic Migrations](docs/ALEMBIC.md)** | Setup, configuration, limitations, batch workarounds |
90
+ | **[Feature Support](docs/FEATURE_SUPPORT.md)** | Full comparison with MySQL, PostgreSQL, and SQLite |
91
+ | **[Development](docs/DEVELOPMENT.md)** | Dev setup, testing, Docker, coverage, CI/CD |
92
+
93
+ ## Compatibility
94
+
95
+ | | Python 3.10 | Python 3.11 | Python 3.12 | Python 3.13 |
96
+ |---|:---:|:---:|:---:|:---:|
97
+ | **Offline Tests** | ✅ | ✅ | ✅ | ✅ |
98
+ | **CUBRID 11.4** | ✅ | — | ✅ | — |
99
+ | **CUBRID 11.2** | ✅ | — | ✅ | — |
100
+ | **CUBRID 11.0** | ✅ | — | ✅ | — |
101
+ | **CUBRID 10.2** | ✅ | — | ✅ | — |
102
+
103
+ ## Contributing
104
+
105
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines. See [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for dev setup.
106
+
107
+ ## Security
108
+
109
+ See [SECURITY.md](SECURITY.md).
110
+
111
+ ## License
112
+
113
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,79 @@
1
+ # sqlalchemy-cubrid
2
+
3
+ CUBRID dialect for SQLAlchemy 2.0+.
4
+
5
+ [![CI](https://github.com/sqlalchemy-cubrid/sqlalchemy-cubrid/actions/workflows/ci.yml/badge.svg)](https://github.com/sqlalchemy-cubrid/sqlalchemy-cubrid/actions/workflows/ci.yml)
6
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/downloads/)
7
+ [![SQLAlchemy 2.0](https://img.shields.io/badge/SQLAlchemy-2.0-green.svg)](https://www.sqlalchemy.org/)
8
+ [![Coverage 99%](https://img.shields.io/badge/coverage-99%25-brightgreen.svg)](docs/DEVELOPMENT.md#code-coverage)
9
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
10
+
11
+ ## Requirements
12
+
13
+ - Python 3.10+
14
+ - SQLAlchemy 2.0 – 2.1
15
+ - [CUBRID-Python](https://github.com/CUBRID/cubrid-python) driver
16
+
17
+ ## Install
18
+
19
+ ```bash
20
+ pip install sqlalchemy-cubrid
21
+ ```
22
+
23
+ ## Quick Start
24
+
25
+ ```python
26
+ from sqlalchemy import create_engine, text
27
+
28
+ engine = create_engine("cubrid://dba:password@localhost:33000/demodb")
29
+
30
+ with engine.connect() as conn:
31
+ result = conn.execute(text("SELECT 1"))
32
+ print(result.scalar())
33
+ ```
34
+
35
+ ## Features
36
+
37
+ - Full SQLAlchemy 2.0 dialect with statement caching
38
+ - Complete type system — numeric, string, date/time, bit, LOB, and collection types
39
+ - SQL compilation — SELECT, JOIN, CAST, LIMIT/OFFSET, subqueries, CTEs, window functions
40
+ - DML extensions — `ON DUPLICATE KEY UPDATE`, `MERGE`, `FOR UPDATE`, `TRUNCATE`
41
+ - DDL support — `COMMENT`, `IF NOT EXISTS` / `IF EXISTS`, `AUTO_INCREMENT`
42
+ - Schema reflection — tables, views, columns, PKs, FKs, indexes, unique constraints, comments
43
+ - Alembic migrations via `CubridImpl` (auto-discovered entry point)
44
+ - All 6 CUBRID isolation levels
45
+ - PEP 561 typed package
46
+
47
+ ## Documentation
48
+
49
+ | Guide | Description |
50
+ |---|---|
51
+ | **[Connection](docs/CONNECTION.md)** | Connection strings, URL format, driver setup, troubleshooting |
52
+ | **[Type Mapping](docs/TYPES.md)** | Full type mapping, CUBRID-specific types, collection types |
53
+ | **[DML Extensions](docs/DML_EXTENSIONS.md)** | ON DUPLICATE KEY UPDATE, MERGE, GROUP_CONCAT, TRUNCATE, index hints |
54
+ | **[Isolation Levels](docs/ISOLATION_LEVELS.md)** | All 6 CUBRID isolation levels, configuration, comparison |
55
+ | **[Alembic Migrations](docs/ALEMBIC.md)** | Setup, configuration, limitations, batch workarounds |
56
+ | **[Feature Support](docs/FEATURE_SUPPORT.md)** | Full comparison with MySQL, PostgreSQL, and SQLite |
57
+ | **[Development](docs/DEVELOPMENT.md)** | Dev setup, testing, Docker, coverage, CI/CD |
58
+
59
+ ## Compatibility
60
+
61
+ | | Python 3.10 | Python 3.11 | Python 3.12 | Python 3.13 |
62
+ |---|:---:|:---:|:---:|:---:|
63
+ | **Offline Tests** | ✅ | ✅ | ✅ | ✅ |
64
+ | **CUBRID 11.4** | ✅ | — | ✅ | — |
65
+ | **CUBRID 11.2** | ✅ | — | ✅ | — |
66
+ | **CUBRID 11.0** | ✅ | — | ✅ | — |
67
+ | **CUBRID 10.2** | ✅ | — | ✅ | — |
68
+
69
+ ## Contributing
70
+
71
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines. See [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for dev setup.
72
+
73
+ ## Security
74
+
75
+ See [SECURITY.md](SECURITY.md).
76
+
77
+ ## License
78
+
79
+ MIT — see [LICENSE](LICENSE).
@@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "sqlalchemy-cubrid"
7
- version = "1.2.1"
7
+ version = "1.2.2"
8
8
  description = "CUBRID dialect for SQLAlchemy"
9
9
  readme = "README.md"
10
- license = "MIT"
10
+ license = {text = "MIT"}
11
11
  requires-python = ">=3.10"
12
12
  authors = [
13
13
  {name = "Yeongseon Choe", email = "yeongseon.choe@gmail.com"},
@@ -15,21 +15,16 @@ authors = [
15
15
  ]
16
16
  keywords = ["SQLAlchemy", "CUBRID", "dialect"]
17
17
  classifiers = [
18
- "Development Status :: 5 - Production/Stable",
18
+ "Development Status :: 3 - Alpha",
19
19
  "Environment :: Console",
20
20
  "Intended Audience :: Developers",
21
- "Operating System :: OS Independent",
21
+ "License :: OSI Approved :: MIT License",
22
22
  "Programming Language :: Python",
23
23
  "Programming Language :: Python :: 3",
24
- "Programming Language :: Python :: 3 :: Only",
25
24
  "Programming Language :: Python :: 3.10",
26
25
  "Programming Language :: Python :: 3.11",
27
26
  "Programming Language :: Python :: 3.12",
28
27
  "Programming Language :: Python :: 3.13",
29
- "Programming Language :: Python :: 3.14",
30
- "Programming Language :: SQL",
31
- "Topic :: Database",
32
- "Topic :: Database :: Front-Ends",
33
28
  ]
34
29
  dependencies = [
35
30
  "sqlalchemy>=2.0,<2.2",
@@ -41,33 +36,20 @@ cubrid = [
41
36
  ]
42
37
  dev = [
43
38
  "pytest>=7.0",
44
- "pytest-cov",
45
- "ruff==0.15.8",
46
- "mypy==1.19.1",
47
- "bandit[toml]==1.9.4",
48
- "pre-commit",
49
- "tox",
50
- "alembic>=1.7",
39
+ "ruff>=0.4",
51
40
  ]
52
41
  alembic = [
53
42
  "alembic>=1.7",
54
43
  ]
55
- pycubrid = [
56
- "pycubrid>=1.0,<2.0",
57
- ]
58
44
 
59
45
  [project.urls]
60
- Homepage = "https://github.com/cubrid-labs/sqlalchemy-cubrid"
61
- Repository = "https://github.com/cubrid-labs/sqlalchemy-cubrid"
62
- Documentation = "https://github.com/cubrid-labs/sqlalchemy-cubrid/tree/main/docs"
63
- Changelog = "https://github.com/cubrid-labs/sqlalchemy-cubrid/blob/main/CHANGELOG.md"
64
- Issues = "https://github.com/cubrid-labs/sqlalchemy-cubrid/issues"
46
+ Homepage = "https://github.com/sqlalchemy-cubrid/sqlalchemy-cubrid"
47
+ Repository = "https://github.com/sqlalchemy-cubrid/sqlalchemy-cubrid"
48
+ Documentation = "https://github.com/sqlalchemy-cubrid/sqlalchemy-cubrid"
65
49
 
66
50
  [project.entry-points."sqlalchemy.dialects"]
67
51
  cubrid = "sqlalchemy_cubrid.dialect:CubridDialect"
68
52
  "cubrid.cubrid" = "sqlalchemy_cubrid.dialect:CubridDialect"
69
- "cubrid.pycubrid" = "sqlalchemy_cubrid.pycubrid_dialect:PyCubridDialect"
70
- "cubrid.aiopycubrid" = "sqlalchemy_cubrid.aio_pycubrid_dialect:PyCubridAsyncDialect"
71
53
 
72
54
  [project.entry-points."alembic.ddl"]
73
55
  cubrid = "sqlalchemy_cubrid.alembic_impl:CubridImpl"
@@ -80,30 +62,6 @@ include-package-data = true
80
62
  line-length = 100
81
63
  target-version = "py310"
82
64
 
83
- [tool.ruff.lint.isort]
84
- known-first-party = ["sqlalchemy_cubrid"]
85
-
86
- [tool.mypy]
87
- python_version = "3.10"
88
- strict = true
89
- warn_return_any = true
90
- warn_unused_configs = true
91
-
92
- [[tool.mypy.overrides]]
93
- module = "test.*"
94
- ignore_errors = true
95
-
96
- [tool.bandit]
97
- exclude_dirs = ["test"]
98
- skips = ["B101"]
99
-
100
- [tool.coverage.run]
101
- source = ["sqlalchemy_cubrid"]
102
-
103
- [tool.coverage.report]
104
- show_missing = true
105
- fail_under = 95
106
-
107
65
  [tool.pytest.ini_options]
108
66
  testpaths = ["test"]
109
67
  addopts = "--tb native -v -r fxX --maxfail=25 -p no:warnings"
@@ -25,15 +25,10 @@ from .types import (
25
25
  DOUBLE,
26
26
  DOUBLE_PRECISION,
27
27
  FLOAT,
28
- JSON,
29
- JSONIndexType,
30
- JSONPathType,
31
- MONETARY,
32
28
  MULTISET,
33
29
  NCHAR,
34
30
  NUMERIC,
35
31
  NVARCHAR,
36
- OBJECT,
37
32
  REAL,
38
33
  SEQUENCE,
39
34
  SET,
@@ -41,8 +36,7 @@ from .types import (
41
36
  STRING,
42
37
  VARCHAR,
43
38
  )
44
- from .dml import insert, merge, replace
45
- from .trace import trace_query
39
+ from .dml import insert, merge
46
40
 
47
41
  from sqlalchemy.sql.sqltypes import (
48
42
  DATE,
@@ -52,13 +46,11 @@ from sqlalchemy.sql.sqltypes import (
52
46
  TIMESTAMP,
53
47
  )
54
48
 
55
- __version__ = "1.2.1"
49
+ __version__ = "1.2.2"
56
50
 
57
51
  __all__ = (
58
52
  "insert",
59
53
  "merge",
60
- "replace",
61
- "trace_query",
62
54
  "SMALLINT",
63
55
  "INTEGER",
64
56
  "BIGINT",
@@ -68,7 +60,6 @@ __all__ = (
68
60
  "REAL",
69
61
  "DOUBLE",
70
62
  "DOUBLE_PRECISION",
71
- "MONETARY",
72
63
  "DATE",
73
64
  "TIME",
74
65
  "TIMESTAMP",
@@ -84,8 +75,4 @@ __all__ = (
84
75
  "SET",
85
76
  "MULTISET",
86
77
  "SEQUENCE",
87
- "OBJECT",
88
- "JSON",
89
- "JSONIndexType",
90
- "JSONPathType",
91
78
  )
@@ -0,0 +1,69 @@
1
+ # sqlalchemy_cubrid/alembic_impl.py
2
+ # Copyright (C) 2021-2026 by sqlalchemy-cubrid authors and contributors
3
+ # <see AUTHORS file>
4
+ #
5
+ # This module is part of sqlalchemy-cubrid and is released under
6
+ # the MIT License: http://www.opensource.org/licenses/mit-license.php
7
+
8
+ """Alembic migration support for the CUBRID dialect.
9
+
10
+ This module provides the Alembic ``DefaultImpl`` subclass that enables
11
+ Alembic migrations against a CUBRID database. It is registered as an
12
+ entry-point under ``alembic.ddl`` so that Alembic auto-discovers it
13
+ when the target database URL uses the ``cubrid://`` scheme.
14
+
15
+ Usage::
16
+
17
+ # alembic.ini
18
+ [alembic]
19
+ sqlalchemy.url = cubrid://dba:password@localhost:33000/demodb
20
+
21
+ # That's it — Alembic will pick up the CUBRID implementation
22
+ # automatically via the ``alembic.ddl`` entry point.
23
+
24
+ CUBRID-specific notes
25
+ ---------------------
26
+ * **DDL is auto-committed** — CUBRID implicitly commits every DDL
27
+ statement, so ``transactional_ddl`` is set to ``False``.
28
+ * **No ALTER COLUMN TYPE** — CUBRID does not support changing a
29
+ column's data type via ``ALTER TABLE … MODIFY``. Alembic's
30
+ ``alter_column(type_=…)`` will raise. Use ``batch_alter_table``
31
+ (table recreate) as a workaround.
32
+ * **No RENAME COLUMN** — CUBRID ≤ 11.x does not support
33
+ ``ALTER TABLE … RENAME COLUMN``. Alembic's ``alter_column(new_column_name=…)``
34
+ will raise. Use ``batch_alter_table`` (table recreate) as a
35
+ workaround.
36
+ """
37
+
38
+ from __future__ import annotations
39
+
40
+ from typing import TYPE_CHECKING
41
+
42
+ try:
43
+ from alembic.ddl.impl import DefaultImpl
44
+ except ImportError: # pragma: no cover — optional dependency
45
+ raise ImportError(
46
+ "Alembic is required for migration support. "
47
+ "Install it with: pip install sqlalchemy-cubrid[alembic]"
48
+ ) from None
49
+
50
+ if TYPE_CHECKING:
51
+ pass
52
+
53
+
54
+ class CubridImpl(DefaultImpl):
55
+ """Alembic migration implementation for CUBRID.
56
+
57
+ Registered via the ``alembic.ddl`` entry-point so Alembic
58
+ auto-discovers it for ``cubrid://`` URLs.
59
+
60
+ Attributes
61
+ ----------
62
+ __dialect__ : str
63
+ ``"cubrid"`` — matches the SQLAlchemy dialect name.
64
+ transactional_ddl : bool
65
+ ``False`` — CUBRID implicitly commits DDL statements.
66
+ """
67
+
68
+ __dialect__ = "cubrid"
69
+ transactional_ddl = False
@@ -10,7 +10,6 @@
10
10
  from __future__ import annotations
11
11
 
12
12
  import re
13
- from typing import Any, cast
14
13
 
15
14
  from sqlalchemy.engine import default
16
15
  from sqlalchemy.sql import compiler
@@ -378,19 +377,19 @@ RESERVED_WORDS = frozenset(
378
377
  class CubridIdentifierPreparer(compiler.IdentifierPreparer):
379
378
  """Quoting logic for CUBRID identifiers."""
380
379
 
381
- reserved_words = set(RESERVED_WORDS)
380
+ reserved_words = RESERVED_WORDS
382
381
 
383
382
  def __init__(
384
383
  self,
385
- dialect: Any,
386
- initial_quote: str = '"',
387
- final_quote: str | None = None,
388
- escape_quote: str = '"',
389
- omit_schema: bool = False,
390
- ) -> None:
384
+ dialect,
385
+ initial_quote='"',
386
+ final_quote=None,
387
+ escape_quote='"',
388
+ omit_schema=False,
389
+ ):
391
390
  super().__init__(dialect, initial_quote, final_quote, escape_quote, omit_schema)
392
391
 
393
- def _quote_free_identifiers(self, *ids: str | None) -> tuple[str, ...]:
392
+ def _quote_free_identifiers(self, *ids):
394
393
  """Unilaterally identifier-quote any number of strings."""
395
394
  return tuple(self.quote_identifier(i) for i in ids if i is not None)
396
395
 
@@ -398,10 +397,10 @@ class CubridIdentifierPreparer(compiler.IdentifierPreparer):
398
397
  class CubridExecutionContext(default.DefaultExecutionContext):
399
398
  """Execution context for CUBRID connections."""
400
399
 
401
- def should_autocommit_text(self, statement: str) -> Any:
400
+ def should_autocommit_text(self, statement):
402
401
  return AUTOCOMMIT_REGEXP.match(statement)
403
402
 
404
- def get_lastrowid(self) -> int:
403
+ def get_lastrowid(self):
405
404
  """Return the last inserted row ID.
406
405
 
407
406
  CUBRID's Python driver does not expose ``cursor.lastrowid``.
@@ -412,10 +411,9 @@ class CubridExecutionContext(default.DefaultExecutionContext):
412
411
  try:
413
412
  # CUBRID Python driver exposes this on the raw connection
414
413
  raw_conn = self.root_connection.connection.dbapi_connection
415
- if raw_conn is not None and hasattr(raw_conn, "get_last_insert_id"):
416
- last_id = raw_conn.get_last_insert_id()
417
- return cast(int, None) if last_id is None else int(last_id) # pyright: ignore[reportInvalidCast]
418
- except Exception: # nosec B110 — fallback to SQL when driver lacks method
414
+ if hasattr(raw_conn, "get_last_insert_id"):
415
+ return raw_conn.get_last_insert_id()
416
+ except Exception:
419
417
  pass
420
418
 
421
419
  # Fallback: use SQL function
@@ -427,4 +425,4 @@ class CubridExecutionContext(default.DefaultExecutionContext):
427
425
  return int(row[0])
428
426
  finally:
429
427
  cursor.close()
430
- return cast(int, None) # pyright: ignore[reportInvalidCast]
428
+ return None