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.
- sqlalchemy_cubrid-1.2.2/PKG-INFO +113 -0
- sqlalchemy_cubrid-1.2.2/README.md +79 -0
- {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/pyproject.toml +8 -50
- {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/sqlalchemy_cubrid/__init__.py +2 -15
- sqlalchemy_cubrid-1.2.2/sqlalchemy_cubrid/alembic_impl.py +69 -0
- {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/sqlalchemy_cubrid/base.py +14 -16
- {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/sqlalchemy_cubrid/compiler.py +58 -140
- {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/sqlalchemy_cubrid/dialect.py +74 -295
- {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/sqlalchemy_cubrid/dml.py +6 -57
- sqlalchemy_cubrid-1.2.2/sqlalchemy_cubrid/requirements.py +270 -0
- {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/sqlalchemy_cubrid/types.py +30 -156
- sqlalchemy_cubrid-1.2.2/sqlalchemy_cubrid.egg-info/PKG-INFO +113 -0
- {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/sqlalchemy_cubrid.egg-info/SOURCES.txt +0 -8
- {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/sqlalchemy_cubrid.egg-info/entry_points.txt +0 -2
- sqlalchemy_cubrid-1.2.2/sqlalchemy_cubrid.egg-info/requires.txt +11 -0
- sqlalchemy_cubrid-1.2.2/test/test_alembic.py +120 -0
- {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/test/test_compiler.py +1 -175
- {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/test/test_dialect_offline.py +20 -314
- {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/test/test_dialects.py +0 -30
- sqlalchemy_cubrid-1.2.2/test/test_integration.py +326 -0
- {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/test/test_types.py +0 -16
- sqlalchemy_cubrid-1.2.1/PKG-INFO +0 -281
- sqlalchemy_cubrid-1.2.1/README.md +0 -232
- sqlalchemy_cubrid-1.2.1/sqlalchemy_cubrid/aio_pycubrid_dialect.py +0 -130
- sqlalchemy_cubrid-1.2.1/sqlalchemy_cubrid/alembic_impl.py +0 -145
- sqlalchemy_cubrid-1.2.1/sqlalchemy_cubrid/pycubrid_dialect.py +0 -129
- sqlalchemy_cubrid-1.2.1/sqlalchemy_cubrid/requirements.py +0 -276
- sqlalchemy_cubrid-1.2.1/sqlalchemy_cubrid/trace.py +0 -92
- sqlalchemy_cubrid-1.2.1/sqlalchemy_cubrid.egg-info/PKG-INFO +0 -281
- sqlalchemy_cubrid-1.2.1/sqlalchemy_cubrid.egg-info/requires.txt +0 -20
- sqlalchemy_cubrid-1.2.1/test/test_aio_integration.py +0 -293
- sqlalchemy_cubrid-1.2.1/test/test_aio_pycubrid_dialect.py +0 -206
- sqlalchemy_cubrid-1.2.1/test/test_alembic.py +0 -261
- sqlalchemy_cubrid-1.2.1/test/test_integration.py +0 -613
- sqlalchemy_cubrid-1.2.1/test/test_json.py +0 -312
- sqlalchemy_cubrid-1.2.1/test/test_pycubrid_dialect.py +0 -306
- sqlalchemy_cubrid-1.2.1/test/test_trace.py +0 -197
- {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/AUTHORS +0 -0
- {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/LICENSE +0 -0
- {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/setup.cfg +0 -0
- {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/sqlalchemy_cubrid/py.typed +0 -0
- {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/sqlalchemy_cubrid.egg-info/dependency_links.txt +0 -0
- {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/sqlalchemy_cubrid.egg-info/top_level.txt +0 -0
- {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/test/test_base.py +0 -0
- {sqlalchemy_cubrid-1.2.1 → sqlalchemy_cubrid-1.2.2}/test/test_requirements.py +0 -0
- {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
|
+
[](https://github.com/sqlalchemy-cubrid/sqlalchemy-cubrid/actions/workflows/ci.yml)
|
|
40
|
+
[](https://www.python.org/downloads/)
|
|
41
|
+
[](https://www.sqlalchemy.org/)
|
|
42
|
+
[](docs/DEVELOPMENT.md#code-coverage)
|
|
43
|
+
[](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
|
+
[](https://github.com/sqlalchemy-cubrid/sqlalchemy-cubrid/actions/workflows/ci.yml)
|
|
6
|
+
[](https://www.python.org/downloads/)
|
|
7
|
+
[](https://www.sqlalchemy.org/)
|
|
8
|
+
[](docs/DEVELOPMENT.md#code-coverage)
|
|
9
|
+
[](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.
|
|
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 ::
|
|
18
|
+
"Development Status :: 3 - Alpha",
|
|
19
19
|
"Environment :: Console",
|
|
20
20
|
"Intended Audience :: Developers",
|
|
21
|
-
"
|
|
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
|
-
"
|
|
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
|
|
61
|
-
Repository = "https://github.com/cubrid
|
|
62
|
-
Documentation = "https://github.com/cubrid
|
|
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
|
|
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.
|
|
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 =
|
|
380
|
+
reserved_words = RESERVED_WORDS
|
|
382
381
|
|
|
383
382
|
def __init__(
|
|
384
383
|
self,
|
|
385
|
-
dialect
|
|
386
|
-
initial_quote
|
|
387
|
-
final_quote
|
|
388
|
-
escape_quote
|
|
389
|
-
omit_schema
|
|
390
|
-
)
|
|
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
|
|
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
|
|
400
|
+
def should_autocommit_text(self, statement):
|
|
402
401
|
return AUTOCOMMIT_REGEXP.match(statement)
|
|
403
402
|
|
|
404
|
-
def get_lastrowid(self)
|
|
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
|
|
416
|
-
|
|
417
|
-
|
|
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
|
|
428
|
+
return None
|