sqlalchemy-cubrid 1.2.0__tar.gz → 1.2.1__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.0/sqlalchemy_cubrid.egg-info → sqlalchemy_cubrid-1.2.1}/PKG-INFO +1 -1
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/pyproject.toml +1 -1
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/sqlalchemy_cubrid/__init__.py +1 -1
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/sqlalchemy_cubrid/aio_pycubrid_dialect.py +5 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/sqlalchemy_cubrid/dialect.py +9 -1
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1/sqlalchemy_cubrid.egg-info}/PKG-INFO +1 -1
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/sqlalchemy_cubrid.egg-info/SOURCES.txt +1 -0
- sqlalchemy_cubrid-1.2.1/test/test_aio_integration.py +293 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/AUTHORS +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/LICENSE +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/README.md +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/setup.cfg +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/sqlalchemy_cubrid/alembic_impl.py +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/sqlalchemy_cubrid/base.py +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/sqlalchemy_cubrid/compiler.py +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/sqlalchemy_cubrid/dml.py +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/sqlalchemy_cubrid/py.typed +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/sqlalchemy_cubrid/pycubrid_dialect.py +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/sqlalchemy_cubrid/requirements.py +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/sqlalchemy_cubrid/trace.py +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/sqlalchemy_cubrid/types.py +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/sqlalchemy_cubrid.egg-info/dependency_links.txt +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/sqlalchemy_cubrid.egg-info/entry_points.txt +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/sqlalchemy_cubrid.egg-info/requires.txt +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/sqlalchemy_cubrid.egg-info/top_level.txt +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/test/test_aio_pycubrid_dialect.py +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/test/test_alembic.py +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/test/test_base.py +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/test/test_compiler.py +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/test/test_dialect_offline.py +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/test/test_dialects.py +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/test/test_integration.py +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/test/test_json.py +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/test/test_pycubrid_dialect.py +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/test/test_requirements.py +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/test/test_suite.py +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/test/test_trace.py +0 -0
- {sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/test/test_types.py +0 -0
{sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/sqlalchemy_cubrid/aio_pycubrid_dialect.py
RENAMED
|
@@ -14,6 +14,7 @@ from sqlalchemy.connectors.asyncio import (
|
|
|
14
14
|
AsyncAdapt_dbapi_cursor,
|
|
15
15
|
AsyncAdapt_dbapi_module,
|
|
16
16
|
)
|
|
17
|
+
from sqlalchemy import pool as pool_module
|
|
17
18
|
from sqlalchemy.engine.interfaces import ConnectArgsType, DBAPIModule
|
|
18
19
|
from sqlalchemy.engine.url import URL
|
|
19
20
|
from sqlalchemy.util.concurrency import await_only
|
|
@@ -79,6 +80,10 @@ class PyCubridAsyncDialect(PyCubridDialect):
|
|
|
79
80
|
supports_statement_cache = True
|
|
80
81
|
execution_ctx_cls = PyCubridExecutionContext
|
|
81
82
|
|
|
83
|
+
@classmethod
|
|
84
|
+
def get_pool_class(cls, url: URL) -> type[pool_module.Pool]:
|
|
85
|
+
return pool_module.AsyncAdaptedQueuePool
|
|
86
|
+
|
|
82
87
|
@classmethod
|
|
83
88
|
def import_dbapi(cls) -> DBAPIModule:
|
|
84
89
|
import pycubrid.aio as aio_module
|
|
@@ -198,9 +198,17 @@ class CubridDialect(default.DefaultDialect):
|
|
|
198
198
|
|
|
199
199
|
postfetch_lastrowid = True
|
|
200
200
|
|
|
201
|
-
def __init__(
|
|
201
|
+
def __init__(
|
|
202
|
+
self,
|
|
203
|
+
isolation_level: str | None = None,
|
|
204
|
+
json_serializer: Any = None,
|
|
205
|
+
json_deserializer: Any = None,
|
|
206
|
+
**kwargs: Any,
|
|
207
|
+
) -> None:
|
|
202
208
|
super().__init__(**kwargs)
|
|
203
209
|
self.isolation_level = isolation_level
|
|
210
|
+
self._json_serializer = json_serializer
|
|
211
|
+
self._json_deserializer = json_deserializer
|
|
204
212
|
|
|
205
213
|
@classmethod
|
|
206
214
|
def import_dbapi(cls) -> DBAPIModule:
|
|
@@ -20,6 +20,7 @@ sqlalchemy_cubrid.egg-info/dependency_links.txt
|
|
|
20
20
|
sqlalchemy_cubrid.egg-info/entry_points.txt
|
|
21
21
|
sqlalchemy_cubrid.egg-info/requires.txt
|
|
22
22
|
sqlalchemy_cubrid.egg-info/top_level.txt
|
|
23
|
+
test/test_aio_integration.py
|
|
23
24
|
test/test_aio_pycubrid_dialect.py
|
|
24
25
|
test/test_alembic.py
|
|
25
26
|
test/test_base.py
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
# test/test_aio_integration.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
|
+
"""Async integration tests against a live CUBRID instance.
|
|
9
|
+
|
|
10
|
+
These tests require a running CUBRID database. They are skipped
|
|
11
|
+
automatically when no CUBRID connection is available.
|
|
12
|
+
|
|
13
|
+
Set the environment variable ``CUBRID_TEST_URL`` to the **sync**
|
|
14
|
+
connection URL. The async URL is derived automatically::
|
|
15
|
+
|
|
16
|
+
export CUBRID_TEST_URL="cubrid://dba@localhost:33000/testdb"
|
|
17
|
+
|
|
18
|
+
The async dialect uses ``cubrid+aiopycubrid://`` as scheme.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
import asyncio
|
|
24
|
+
import json
|
|
25
|
+
import os
|
|
26
|
+
|
|
27
|
+
import pytest
|
|
28
|
+
import pytest_asyncio
|
|
29
|
+
from sqlalchemy import Column, Integer, MetaData, String, Table, text
|
|
30
|
+
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
|
|
31
|
+
from sqlalchemy.orm import sessionmaker
|
|
32
|
+
|
|
33
|
+
# ---------------------------------------------------------------------------
|
|
34
|
+
# Fixtures
|
|
35
|
+
# ---------------------------------------------------------------------------
|
|
36
|
+
|
|
37
|
+
_DEFAULT_SYNC_URL = "cubrid://dba@localhost:33000/testdb"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _async_url() -> str:
|
|
41
|
+
"""Derive the async URL from the sync one."""
|
|
42
|
+
sync = os.environ.get("CUBRID_TEST_URL", _DEFAULT_SYNC_URL)
|
|
43
|
+
return sync.replace("cubrid://", "cubrid+aiopycubrid://", 1)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _can_connect_async() -> bool:
|
|
47
|
+
"""Return True if a CUBRID instance is reachable via async."""
|
|
48
|
+
try:
|
|
49
|
+
engine = create_async_engine(_async_url())
|
|
50
|
+
|
|
51
|
+
async def _probe() -> bool:
|
|
52
|
+
async with engine.connect() as conn:
|
|
53
|
+
await conn.execute(text("SELECT 1"))
|
|
54
|
+
await engine.dispose()
|
|
55
|
+
return True
|
|
56
|
+
|
|
57
|
+
return asyncio.get_event_loop().run_until_complete(_probe())
|
|
58
|
+
except Exception:
|
|
59
|
+
return False
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
pytestmark = [
|
|
63
|
+
pytest.mark.skipif(
|
|
64
|
+
not _can_connect_async(),
|
|
65
|
+
reason="CUBRID async instance not available (set CUBRID_TEST_URL)",
|
|
66
|
+
),
|
|
67
|
+
pytest.mark.asyncio,
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@pytest_asyncio.fixture(scope="module")
|
|
72
|
+
def event_loop():
|
|
73
|
+
"""Create a single event loop for the module."""
|
|
74
|
+
loop = asyncio.new_event_loop()
|
|
75
|
+
yield loop
|
|
76
|
+
loop.close()
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@pytest_asyncio.fixture(scope="module")
|
|
80
|
+
async def engine():
|
|
81
|
+
eng = create_async_engine(_async_url(), echo=False)
|
|
82
|
+
yield eng
|
|
83
|
+
await eng.dispose()
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@pytest_asyncio.fixture(scope="module")
|
|
87
|
+
async def metadata(engine):
|
|
88
|
+
meta = MetaData()
|
|
89
|
+
Table(
|
|
90
|
+
"aio_test_users",
|
|
91
|
+
meta,
|
|
92
|
+
Column("id", Integer, primary_key=True, autoincrement=True),
|
|
93
|
+
Column("name", String(100), nullable=False),
|
|
94
|
+
Column("value", Integer),
|
|
95
|
+
)
|
|
96
|
+
async with engine.begin() as conn:
|
|
97
|
+
await conn.execute(text("DROP TABLE IF EXISTS aio_test_users"))
|
|
98
|
+
await conn.run_sync(meta.create_all)
|
|
99
|
+
yield meta
|
|
100
|
+
async with engine.begin() as conn:
|
|
101
|
+
await conn.execute(text("DROP TABLE IF EXISTS aio_test_users"))
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
# ---------------------------------------------------------------------------
|
|
105
|
+
# Phase 2: Async CRUD + Transaction
|
|
106
|
+
# ---------------------------------------------------------------------------
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
class TestAsyncCRUD:
|
|
110
|
+
"""Async CRUD round-trip tests."""
|
|
111
|
+
|
|
112
|
+
async def test_connect(self, engine):
|
|
113
|
+
async with engine.connect() as conn:
|
|
114
|
+
result = await conn.execute(text("SELECT 1"))
|
|
115
|
+
assert result.fetchone() == (1,)
|
|
116
|
+
|
|
117
|
+
async def test_insert_and_select(self, engine, metadata):
|
|
118
|
+
users = metadata.tables["aio_test_users"]
|
|
119
|
+
async with engine.begin() as conn:
|
|
120
|
+
await conn.execute(
|
|
121
|
+
users.insert(),
|
|
122
|
+
[{"name": "alice", "value": 10}, {"name": "bob", "value": 20}],
|
|
123
|
+
)
|
|
124
|
+
async with engine.connect() as conn:
|
|
125
|
+
result = await conn.execute(users.select())
|
|
126
|
+
rows = result.fetchall()
|
|
127
|
+
assert len(rows) >= 2
|
|
128
|
+
|
|
129
|
+
async def test_update(self, engine, metadata):
|
|
130
|
+
users = metadata.tables["aio_test_users"]
|
|
131
|
+
async with engine.begin() as conn:
|
|
132
|
+
await conn.execute(
|
|
133
|
+
users.update().where(users.c.name == "alice").values(value=100)
|
|
134
|
+
)
|
|
135
|
+
async with engine.connect() as conn:
|
|
136
|
+
result = await conn.execute(
|
|
137
|
+
users.select().where(users.c.name == "alice")
|
|
138
|
+
)
|
|
139
|
+
row = result.fetchone()
|
|
140
|
+
assert row is not None and row.value == 100
|
|
141
|
+
|
|
142
|
+
async def test_delete(self, engine, metadata):
|
|
143
|
+
users = metadata.tables["aio_test_users"]
|
|
144
|
+
async with engine.begin() as conn:
|
|
145
|
+
await conn.execute(users.delete().where(users.c.name == "bob"))
|
|
146
|
+
async with engine.connect() as conn:
|
|
147
|
+
result = await conn.execute(
|
|
148
|
+
users.select().where(users.c.name == "bob")
|
|
149
|
+
)
|
|
150
|
+
assert result.fetchone() is None
|
|
151
|
+
|
|
152
|
+
async def test_transaction_rollback(self, engine, metadata):
|
|
153
|
+
users = metadata.tables["aio_test_users"]
|
|
154
|
+
try:
|
|
155
|
+
async with engine.begin() as conn:
|
|
156
|
+
await conn.execute(
|
|
157
|
+
users.insert().values(name="will_rollback", value=999)
|
|
158
|
+
)
|
|
159
|
+
raise RuntimeError("force rollback")
|
|
160
|
+
except RuntimeError:
|
|
161
|
+
pass
|
|
162
|
+
|
|
163
|
+
async with engine.connect() as conn:
|
|
164
|
+
result = await conn.execute(
|
|
165
|
+
users.select().where(users.c.name == "will_rollback")
|
|
166
|
+
)
|
|
167
|
+
assert result.fetchone() is None
|
|
168
|
+
|
|
169
|
+
async def test_concurrent_pool(self, engine):
|
|
170
|
+
async def worker(i: int) -> int:
|
|
171
|
+
async with engine.connect() as conn:
|
|
172
|
+
r = await conn.execute(text(f"SELECT {i}"))
|
|
173
|
+
return r.scalar()
|
|
174
|
+
|
|
175
|
+
results = await asyncio.gather(*[worker(i) for i in range(5)])
|
|
176
|
+
assert sorted(results) == [0, 1, 2, 3, 4]
|
|
177
|
+
|
|
178
|
+
async def test_bad_sql_raises(self, engine):
|
|
179
|
+
with pytest.raises(Exception):
|
|
180
|
+
async with engine.connect() as conn:
|
|
181
|
+
await conn.execute(text("SELECT * FROM nonexistent_xyz"))
|
|
182
|
+
|
|
183
|
+
async def test_autocommit_toggle(self, engine):
|
|
184
|
+
async with engine.connect() as conn:
|
|
185
|
+
raw = await conn.get_raw_connection()
|
|
186
|
+
raw.autocommit = True
|
|
187
|
+
raw.autocommit = False
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
# ---------------------------------------------------------------------------
|
|
191
|
+
# Phase 3: JSON
|
|
192
|
+
# ---------------------------------------------------------------------------
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
class TestAsyncJSON:
|
|
196
|
+
"""JSON type round-trip tests."""
|
|
197
|
+
|
|
198
|
+
@pytest_asyncio.fixture(autouse=True)
|
|
199
|
+
async def _json_table(self, engine):
|
|
200
|
+
async with engine.begin() as conn:
|
|
201
|
+
await conn.execute(text("DROP TABLE IF EXISTS aio_test_json"))
|
|
202
|
+
await conn.execute(
|
|
203
|
+
text(
|
|
204
|
+
"CREATE TABLE aio_test_json ("
|
|
205
|
+
" id INT AUTO_INCREMENT PRIMARY KEY,"
|
|
206
|
+
" payload JSON"
|
|
207
|
+
")"
|
|
208
|
+
)
|
|
209
|
+
)
|
|
210
|
+
yield
|
|
211
|
+
async with engine.begin() as conn:
|
|
212
|
+
await conn.execute(text("DROP TABLE IF EXISTS aio_test_json"))
|
|
213
|
+
|
|
214
|
+
async def _insert_json(self, engine, value):
|
|
215
|
+
async with engine.begin() as conn:
|
|
216
|
+
await conn.execute(
|
|
217
|
+
text("INSERT INTO aio_test_json (payload) VALUES (:p)"),
|
|
218
|
+
{"p": json.dumps(value) if value is not None else None},
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
async def _last_json(self, engine):
|
|
222
|
+
async with engine.connect() as conn:
|
|
223
|
+
r = await conn.execute(
|
|
224
|
+
text("SELECT payload FROM aio_test_json ORDER BY id DESC LIMIT 1")
|
|
225
|
+
)
|
|
226
|
+
raw = r.scalar()
|
|
227
|
+
return json.loads(raw) if isinstance(raw, str) else raw
|
|
228
|
+
|
|
229
|
+
async def test_dict_roundtrip(self, engine):
|
|
230
|
+
d = {"key": "value", "n": 42}
|
|
231
|
+
await self._insert_json(engine, d)
|
|
232
|
+
assert await self._last_json(engine) == d
|
|
233
|
+
|
|
234
|
+
async def test_list_roundtrip(self, engine):
|
|
235
|
+
lst = [1, "two", 3.0, None]
|
|
236
|
+
await self._insert_json(engine, lst)
|
|
237
|
+
assert await self._last_json(engine) == lst
|
|
238
|
+
|
|
239
|
+
async def test_nested_roundtrip(self, engine):
|
|
240
|
+
nested = {"a": {"b": [1, {"c": True}]}}
|
|
241
|
+
await self._insert_json(engine, nested)
|
|
242
|
+
assert await self._last_json(engine) == nested
|
|
243
|
+
|
|
244
|
+
async def test_null_json(self, engine):
|
|
245
|
+
async with engine.begin() as conn:
|
|
246
|
+
await conn.execute(
|
|
247
|
+
text("INSERT INTO aio_test_json (payload) VALUES (NULL)")
|
|
248
|
+
)
|
|
249
|
+
assert await self._last_json(engine) is None
|
|
250
|
+
|
|
251
|
+
async def test_empty_object(self, engine):
|
|
252
|
+
await self._insert_json(engine, {})
|
|
253
|
+
assert await self._last_json(engine) == {}
|
|
254
|
+
|
|
255
|
+
async def test_empty_array(self, engine):
|
|
256
|
+
await self._insert_json(engine, [])
|
|
257
|
+
assert await self._last_json(engine) == []
|
|
258
|
+
|
|
259
|
+
async def test_json_extract(self, engine):
|
|
260
|
+
async with engine.connect() as conn:
|
|
261
|
+
r = await conn.execute(
|
|
262
|
+
text("SELECT JSON_EXTRACT('{\"a\": 1}', '$.a')")
|
|
263
|
+
)
|
|
264
|
+
assert r.scalar() is not None
|
|
265
|
+
|
|
266
|
+
async def test_orm_json_type(self, engine):
|
|
267
|
+
from sqlalchemy_cubrid.types import JSON as CubridJSON
|
|
268
|
+
|
|
269
|
+
meta = MetaData()
|
|
270
|
+
t = Table(
|
|
271
|
+
"aio_test_json_orm",
|
|
272
|
+
meta,
|
|
273
|
+
Column("id", Integer, primary_key=True, autoincrement=True),
|
|
274
|
+
Column("data", CubridJSON),
|
|
275
|
+
)
|
|
276
|
+
async with engine.begin() as conn:
|
|
277
|
+
await conn.execute(text("DROP TABLE IF EXISTS aio_test_json_orm"))
|
|
278
|
+
await conn.run_sync(meta.create_all)
|
|
279
|
+
|
|
280
|
+
test_data = {"items": [1, 2, 3]}
|
|
281
|
+
async with engine.begin() as conn:
|
|
282
|
+
await conn.execute(t.insert().values(data=test_data))
|
|
283
|
+
|
|
284
|
+
async with engine.connect() as conn:
|
|
285
|
+
r = await conn.execute(t.select())
|
|
286
|
+
row = r.fetchone()
|
|
287
|
+
val = row.data
|
|
288
|
+
if isinstance(val, str):
|
|
289
|
+
val = json.loads(val)
|
|
290
|
+
assert val == test_data
|
|
291
|
+
|
|
292
|
+
async with engine.begin() as conn:
|
|
293
|
+
await conn.execute(text("DROP TABLE IF EXISTS aio_test_json_orm"))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/sqlalchemy_cubrid.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/sqlalchemy_cubrid.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
{sqlalchemy_cubrid-1.2.0 → sqlalchemy_cubrid-1.2.1}/sqlalchemy_cubrid.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|