sqlalchemy-iris 0.16.1b1__tar.gz → 0.17.0__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 (93) hide show
  1. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/PKG-INFO +23 -1
  2. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/README.md +20 -0
  3. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/setup.cfg +6 -1
  4. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/setup.py +1 -0
  5. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/sqlalchemy_iris/__init__.py +3 -2
  6. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/sqlalchemy_iris/base.py +5 -1
  7. sqlalchemy_iris-0.17.0/sqlalchemy_iris/intersystems/__init__.py +167 -0
  8. sqlalchemy_iris-0.17.0/sqlalchemy_iris/intersystems/cursor.py +17 -0
  9. sqlalchemy_iris-0.17.0/sqlalchemy_iris/intersystems/dbapi.py +67 -0
  10. sqlalchemy_iris-0.17.0/sqlalchemy_iris/requirements.py +1509 -0
  11. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/sqlalchemy_iris/types.py +32 -0
  12. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/sqlalchemy_iris.egg-info/PKG-INFO +23 -1
  13. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/sqlalchemy_iris.egg-info/SOURCES.txt +3 -0
  14. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/sqlalchemy_iris.egg-info/entry_points.txt +1 -0
  15. sqlalchemy_iris-0.17.0/sqlalchemy_iris.egg-info/requires.txt +4 -0
  16. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/tests/test_suite.py +4 -4
  17. sqlalchemy_iris-0.16.1b1/sqlalchemy_iris/requirements.py +0 -289
  18. sqlalchemy_iris-0.16.1b1/sqlalchemy_iris.egg-info/requires.txt +0 -1
  19. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/LICENSE +0 -0
  20. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_BufferReader.py +0 -0
  21. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_BufferWriter.py +0 -0
  22. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_ConnectionInformation.py +0 -0
  23. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_ConnectionParameters.py +0 -0
  24. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_Constant.py +0 -0
  25. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_DBList.py +0 -0
  26. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_Device.py +0 -0
  27. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_GatewayContext.py +0 -0
  28. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_GatewayException.py +0 -0
  29. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_GatewayUtility.py +0 -0
  30. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_IRIS.py +0 -0
  31. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_IRISConnection.py +0 -0
  32. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_IRISEmbedded.py +0 -0
  33. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_IRISGlobalNode.py +0 -0
  34. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_IRISGlobalNodeView.py +0 -0
  35. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_IRISIterator.py +0 -0
  36. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_IRISList.py +0 -0
  37. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_IRISNative.py +0 -0
  38. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_IRISOREF.py +0 -0
  39. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_IRISObject.py +0 -0
  40. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_IRISReference.py +0 -0
  41. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_InStream.py +0 -0
  42. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_LegacyIterator.py +0 -0
  43. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_ListItem.py +0 -0
  44. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_ListReader.py +0 -0
  45. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_ListWriter.py +0 -0
  46. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_LogFileStream.py +0 -0
  47. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_MessageHeader.py +0 -0
  48. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_OutStream.py +0 -0
  49. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_PrintStream.py +0 -0
  50. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_PythonGateway.py +0 -0
  51. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/_SharedMemorySocket.py +0 -0
  52. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/__init__.py +0 -0
  53. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/__main__.py +0 -0
  54. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/dbapi/_Column.py +0 -0
  55. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/dbapi/_DBAPI.py +0 -0
  56. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/dbapi/_Descriptor.py +0 -0
  57. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/dbapi/_IRISStream.py +0 -0
  58. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/dbapi/_Message.py +0 -0
  59. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/dbapi/_Parameter.py +0 -0
  60. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/dbapi/_ParameterCollection.py +0 -0
  61. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/dbapi/_ResultSetRow.py +0 -0
  62. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/dbapi/_SQLType.py +0 -0
  63. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/dbapi/__init__.py +0 -0
  64. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/dbapi/preparser/_PreParser.py +0 -0
  65. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/dbapi/preparser/_Scanner.py +0 -0
  66. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/dbapi/preparser/_Token.py +0 -0
  67. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/dbapi/preparser/_TokenList.py +0 -0
  68. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/dbapi/preparser/__init__.py +0 -0
  69. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/pex/_BusinessHost.py +0 -0
  70. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/pex/_BusinessOperation.py +0 -0
  71. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/pex/_BusinessProcess.py +0 -0
  72. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/pex/_BusinessService.py +0 -0
  73. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/pex/_Common.py +0 -0
  74. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/pex/_Director.py +0 -0
  75. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/pex/_IRISBusinessOperation.py +0 -0
  76. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/pex/_IRISBusinessService.py +0 -0
  77. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/pex/_IRISInboundAdapter.py +0 -0
  78. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/pex/_IRISOutboundAdapter.py +0 -0
  79. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/pex/_InboundAdapter.py +0 -0
  80. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/pex/_Message.py +0 -0
  81. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/pex/_OutboundAdapter.py +0 -0
  82. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/intersystems_iris/pex/__init__.py +0 -0
  83. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/irisnative/_IRISNative.py +0 -0
  84. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/irisnative/__init__.py +0 -0
  85. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/sqlalchemy_iris/alembic.py +0 -0
  86. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/sqlalchemy_iris/embedded.py +0 -0
  87. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/sqlalchemy_iris/information_schema.py +0 -0
  88. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/sqlalchemy_iris/iris.py +0 -0
  89. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/sqlalchemy_iris/irisasync.py +0 -0
  90. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/sqlalchemy_iris/provision.py +0 -0
  91. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/sqlalchemy_iris.egg-info/dependency_links.txt +0 -0
  92. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/sqlalchemy_iris.egg-info/top_level.txt +0 -0
  93. {sqlalchemy_iris-0.16.1b1 → sqlalchemy_iris-0.17.0}/tests/test_alembic.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: sqlalchemy-iris
3
- Version: 0.16.1b1
3
+ Version: 0.17.0
4
4
  Summary: InterSystems IRIS for SQLAlchemy
5
5
  Home-page: https://github.com/caretdev/sqlalchemy-iris
6
6
  Maintainer: CaretDev
@@ -23,6 +23,8 @@ Requires-Python: >=3.8
23
23
  Description-Content-Type: text/markdown
24
24
  License-File: LICENSE
25
25
  Requires-Dist: SQLAlchemy>=1.3
26
+ Provides-Extra: intersystems
27
+ Requires-Dist: intersystems-irispython==5.1.0; extra == "intersystems"
26
28
  Dynamic: requires-dist
27
29
 
28
30
  sqlalchemy-iris
@@ -40,6 +42,12 @@ will install them if they are not already in place. To install, just:
40
42
  pip install sqlalchemy-iris
41
43
  ```
42
44
 
45
+ Or to use InterSystems official driver support
46
+
47
+ ```shell
48
+ pip install sqlalchemy-iris[intersystems]
49
+ ```
50
+
43
51
  Usage
44
52
  ---
45
53
 
@@ -50,6 +58,20 @@ from sqlalchemy import create_engine
50
58
  engine = create_engine("iris://_SYSTEM:SYS@localhost:1972/USER")
51
59
  ```
52
60
 
61
+ To use with Python Embedded mode, when run next to IRIS
62
+
63
+ ```python
64
+ from sqlalchemy import create_engine
65
+ engine = create_engine("iris+emb:///USER")
66
+ ```
67
+
68
+ To use with InterSystems official driver, does not work in Python Embedded mode
69
+
70
+ ```python
71
+ from sqlalchemy import create_engine
72
+ engine = create_engine("iris+intersystems://_SYSTEM:SYS@localhost:1972/USER")
73
+ ```
74
+
53
75
  IRIS Cloud SQL requires SSLContext
54
76
 
55
77
  ```python
@@ -13,6 +13,12 @@ will install them if they are not already in place. To install, just:
13
13
  pip install sqlalchemy-iris
14
14
  ```
15
15
 
16
+ Or to use InterSystems official driver support
17
+
18
+ ```shell
19
+ pip install sqlalchemy-iris[intersystems]
20
+ ```
21
+
16
22
  Usage
17
23
  ---
18
24
 
@@ -23,6 +29,20 @@ from sqlalchemy import create_engine
23
29
  engine = create_engine("iris://_SYSTEM:SYS@localhost:1972/USER")
24
30
  ```
25
31
 
32
+ To use with Python Embedded mode, when run next to IRIS
33
+
34
+ ```python
35
+ from sqlalchemy import create_engine
36
+ engine = create_engine("iris+emb:///USER")
37
+ ```
38
+
39
+ To use with InterSystems official driver, does not work in Python Embedded mode
40
+
41
+ ```python
42
+ from sqlalchemy import create_engine
43
+ engine = create_engine("iris+intersystems://_SYSTEM:SYS@localhost:1972/USER")
44
+ ```
45
+
26
46
  IRIS Cloud SQL requires SSLContext
27
47
 
28
48
  ```python
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = sqlalchemy-iris
3
- version = 0.16.1b1
3
+ version = 0.17.0
4
4
  description = InterSystems IRIS for SQLAlchemy
5
5
  long_description = file: README.md
6
6
  url = https://github.com/caretdev/sqlalchemy-iris
@@ -28,12 +28,17 @@ project_urls =
28
28
  python_requires = >=3.8
29
29
  packages = find:
30
30
 
31
+ [options.extras_require]
32
+ intersystems =
33
+ intersystems-irispython==5.1.0
34
+
31
35
  [tool:pytest]
32
36
  addopts = --tb native -v -r fxX --maxfail=25 -p no:warnings
33
37
 
34
38
  [db]
35
39
  default = iris://_SYSTEM:SYS@localhost:1972/USER
36
40
  iris = iris://_SYSTEM:SYS@localhost:1972/USER
41
+ irisintersystems = iris+intersystems://_SYSTEM:SYS@localhost:1972/USER
37
42
  irisasync = iris+irisasync://_SYSTEM:SYS@localhost:1972/USER
38
43
  irisemb = iris+emb:///
39
44
  sqlite = sqlite:///:memory:
@@ -9,6 +9,7 @@ setup(
9
9
  "iris = sqlalchemy_iris.iris:IRISDialect_iris",
10
10
  "iris.emb = sqlalchemy_iris.embedded:IRISDialect_emb",
11
11
  "iris.irisasync = sqlalchemy_iris.irisasync:IRISDialect_irisasync",
12
+ "iris.intersystems = sqlalchemy_iris.intersystems:IRISDialect_intersystems",
12
13
  ]
13
14
  },
14
15
  )
@@ -4,11 +4,11 @@ from . import base
4
4
  from . import iris
5
5
 
6
6
  try:
7
- import alembic
7
+ import alembic # noqa
8
8
  except ImportError:
9
9
  pass
10
10
  else:
11
- from .alembic import IRISImpl
11
+ from .alembic import IRISImpl # noqa
12
12
 
13
13
  from .base import BIGINT
14
14
  from .base import BIT
@@ -32,6 +32,7 @@ base.dialect = dialect = iris.dialect
32
32
  _registry.register("iris.iris", "sqlalchemy_iris.iris", "IRISDialect_iris")
33
33
  _registry.register("iris.emb", "sqlalchemy_iris.embedded", "IRISDialect_emb")
34
34
  _registry.register("iris.irisasync", "sqlalchemy_iris.irisasync", "IRISDialect_irisasync")
35
+ _registry.register("iris.intersystems", "sqlalchemy_iris.intersystems", "IRISDialect_intersystems")
35
36
 
36
37
  __all__ = [
37
38
  "BIGINT",
@@ -900,6 +900,7 @@ class IRISDialect(default.DefaultDialect):
900
900
  type_compiler = IRISTypeCompiler
901
901
  execution_ctx_cls = IRISExecutionContext
902
902
 
903
+ update_returning = False
903
904
  insert_returning = True
904
905
  insert_executemany_returning = True
905
906
  insert_executemany_returning_sort_by_parameter_order = True
@@ -1090,7 +1091,10 @@ There are no access to %Dictionary, may be required for some advanced features,
1090
1091
  if query.endswith(";"):
1091
1092
  query = query[:-1]
1092
1093
  self._debug(query, params)
1093
- cursor.execute(query, params)
1094
+ try:
1095
+ cursor.execute(query, params)
1096
+ except Exception as ex:
1097
+ raise ex
1094
1098
 
1095
1099
  def do_executemany(self, cursor, query, params, context=None):
1096
1100
  if query.endswith(";"):
@@ -0,0 +1,167 @@
1
+ import re
2
+ import pkg_resources
3
+ from ..base import IRISDialect
4
+ from sqlalchemy import text, util
5
+ from ..base import IRISExecutionContext
6
+ from . import dbapi
7
+ from .dbapi import connect, Cursor
8
+ from .cursor import InterSystemsCursorFetchStrategy
9
+ from .dbapi import IntegrityError, OperationalError, DatabaseError
10
+
11
+
12
+ def remap_exception(func):
13
+ def wrapper(cursor, *args, **kwargs):
14
+ attempt = 0
15
+ while attempt < 3:
16
+ attempt += 1
17
+ try:
18
+ cursor.sqlcode = 0
19
+ return func(cursor, *args, **kwargs)
20
+ except RuntimeError as ex:
21
+ # [SQLCODE: <-119>:...
22
+ message = ex.args[0]
23
+ if '<LIST ERROR>' in message:
24
+ # just random error happens in the driver, try again
25
+ continue
26
+ sqlcode = re.findall(r"^\[SQLCODE: <(-\d+)>:", message)
27
+ if not sqlcode:
28
+ raise Exception(message)
29
+ sqlcode = int(sqlcode[0])
30
+ if abs(sqlcode) in [108, 119, 121, 122]:
31
+ raise IntegrityError(message)
32
+ if abs(sqlcode) in [1, 12]:
33
+ raise OperationalError(message)
34
+ raise DatabaseError(message)
35
+
36
+ return wrapper
37
+
38
+
39
+ class InterSystemsExecutionContext(IRISExecutionContext):
40
+ cursor_fetch_strategy = InterSystemsCursorFetchStrategy()
41
+
42
+ def create_cursor(self):
43
+ cursor = self._dbapi_connection.cursor()
44
+ cursor.sqlcode = 0
45
+ return cursor
46
+
47
+
48
+ class IRISDialect_intersystems(IRISDialect):
49
+ driver = "intersystems"
50
+
51
+ execution_ctx_cls = InterSystemsExecutionContext
52
+
53
+ supports_statement_cache = True
54
+
55
+ supports_cte = False
56
+
57
+ supports_sane_rowcount = False
58
+ supports_sane_multi_rowcount = False
59
+
60
+ insert_returning = False
61
+ insert_executemany_returning = False
62
+
63
+ logfile = None
64
+
65
+ def __init__(self, logfile: str = None, **kwargs):
66
+ self.logfile = logfile
67
+ IRISDialect.__init__(self, **kwargs)
68
+
69
+ @classmethod
70
+ def import_dbapi(cls):
71
+ return dbapi
72
+
73
+ def connect(self, *cargs, **kwarg):
74
+ host = kwarg.get("hostname", "localhost")
75
+ port = kwarg.get("port", 1972)
76
+ namespace = kwarg.get("namespace", "USER")
77
+ username = kwarg.get("username", "_SYSTEM")
78
+ password = kwarg.get("password", "SYS")
79
+ timeout = kwarg.get("timeout", 10)
80
+ sharedmemory = kwarg.get("sharedmemory", False)
81
+ logfile = kwarg.get("logfile", self.logfile)
82
+ sslconfig = kwarg.get("sslconfig", False)
83
+ autoCommit = kwarg.get("autoCommit", False)
84
+ isolationLevel = kwarg.get("isolationLevel", 1)
85
+ return connect(
86
+ host,
87
+ port,
88
+ namespace,
89
+ username,
90
+ password,
91
+ timeout,
92
+ sharedmemory,
93
+ logfile,
94
+ sslconfig,
95
+ autoCommit,
96
+ isolationLevel,
97
+ )
98
+
99
+ def create_connect_args(self, url):
100
+ opts = {}
101
+
102
+ opts["application_name"] = "sqlalchemy"
103
+ opts["host"] = url.host
104
+ opts["port"] = int(url.port) if url.port else 1972
105
+ opts["namespace"] = url.database if url.database else "USER"
106
+ opts["username"] = url.username if url.username else ""
107
+ opts["password"] = url.password if url.password else ""
108
+
109
+ opts["autoCommit"] = False
110
+
111
+ if opts["host"] and "@" in opts["host"]:
112
+ _h = opts["host"].split("@")
113
+ opts["password"] += "@" + _h[0 : len(_h) - 1].join("@")
114
+ opts["host"] = _h[len(_h) - 1]
115
+
116
+ return ([], opts)
117
+
118
+ def _get_server_version_info(self, connection):
119
+ # get the wheel version from iris module
120
+ try:
121
+ return tuple(
122
+ map(
123
+ int,
124
+ pkg_resources.get_distribution(
125
+ "intersystems_irispython"
126
+ ).version.split("."),
127
+ )
128
+ )
129
+ except: # noqa
130
+ return None
131
+
132
+ def _get_option(self, connection, option):
133
+ with connection.cursor() as cursor:
134
+ cursor.execute("SELECT %SYSTEM_SQL.Util_GetOption(?)", (option,))
135
+ row = cursor.fetchone()
136
+ if row:
137
+ return row[0]
138
+ return None
139
+
140
+ def set_isolation_level(self, connection, level_str):
141
+ if level_str == "AUTOCOMMIT":
142
+ connection.autocommit = True
143
+ else:
144
+ connection.autocommit = False
145
+ if level_str not in ["READ COMMITTED", "READ VERIFIED"]:
146
+ level_str = "READ UNCOMMITTED"
147
+ with connection.cursor() as cursor:
148
+ cursor.execute("SET TRANSACTION ISOLATION LEVEL " + level_str)
149
+
150
+ @remap_exception
151
+ def do_execute(self, cursor, query, params, context=None):
152
+ if query.endswith(";"):
153
+ query = query[:-1]
154
+ self._debug(query, params)
155
+ cursor.execute(query, params)
156
+
157
+ @remap_exception
158
+ def do_executemany(self, cursor, query, params, context=None):
159
+ if query.endswith(";"):
160
+ query = query[:-1]
161
+ self._debug(query, params, many=True)
162
+ if params and (len(params[0]) <= 1):
163
+ params = [param[0] if len(param) else None for param in params]
164
+ cursor.executemany(query, params)
165
+
166
+
167
+ dialect = IRISDialect_intersystems
@@ -0,0 +1,17 @@
1
+ from typing import Any
2
+ from sqlalchemy import CursorResult
3
+ from sqlalchemy.engine.cursor import CursorFetchStrategy
4
+ from sqlalchemy.engine.interfaces import DBAPICursor
5
+
6
+
7
+ class InterSystemsCursorFetchStrategy(CursorFetchStrategy):
8
+
9
+ def fetchone(
10
+ self,
11
+ result: CursorResult[Any],
12
+ dbapi_cursor: DBAPICursor,
13
+ hard_close: bool = False,
14
+ ) -> Any:
15
+ row = dbapi_cursor.fetchone()
16
+ return tuple(row) if row else None
17
+
@@ -0,0 +1,67 @@
1
+ try:
2
+ import iris
3
+
4
+ class Cursor(iris.irissdk.dbapiCursor):
5
+ pass
6
+
7
+ class DataRow(iris.irissdk.dbapiDataRow):
8
+ pass
9
+
10
+ except ImportError:
11
+ pass
12
+
13
+
14
+ def connect(*args, **kwargs):
15
+ return iris.connect(*args, **kwargs)
16
+
17
+
18
+ # globals
19
+ apilevel = "2.0"
20
+ threadsafety = 0
21
+ paramstyle = "qmark"
22
+
23
+ Binary = bytes
24
+ STRING = str
25
+ BINARY = bytes
26
+ NUMBER = float
27
+ ROWID = str
28
+
29
+
30
+ class Error(Exception):
31
+ pass
32
+
33
+
34
+ class Warning(Exception):
35
+ pass
36
+
37
+
38
+ class InterfaceError(Error):
39
+ pass
40
+
41
+
42
+ class DatabaseError(Error):
43
+ pass
44
+
45
+
46
+ class InternalError(DatabaseError):
47
+ pass
48
+
49
+
50
+ class OperationalError(DatabaseError):
51
+ pass
52
+
53
+
54
+ class ProgrammingError(DatabaseError):
55
+ pass
56
+
57
+
58
+ class IntegrityError(DatabaseError):
59
+ pass
60
+
61
+
62
+ class DataError(DatabaseError):
63
+ pass
64
+
65
+
66
+ class NotSupportedError(DatabaseError):
67
+ pass