sqlalchemy-iris 0.17.0__tar.gz → 0.17.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.
Files changed (91) hide show
  1. {sqlalchemy_iris-0.17.0/sqlalchemy_iris.egg-info → sqlalchemy_iris-0.17.1}/PKG-INFO +57 -2
  2. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/README.md +54 -0
  3. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/setup.cfg +2 -2
  4. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/sqlalchemy_iris/base.py +6 -8
  5. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/sqlalchemy_iris/intersystems/__init__.py +42 -34
  6. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/sqlalchemy_iris/intersystems/dbapi.py +4 -0
  7. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/sqlalchemy_iris/requirements.py +2 -2
  8. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1/sqlalchemy_iris.egg-info}/PKG-INFO +57 -2
  9. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/sqlalchemy_iris.egg-info/SOURCES.txt +0 -1
  10. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/tests/test_alembic.py +41 -8
  11. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/tests/test_suite.py +0 -1
  12. sqlalchemy_iris-0.17.0/sqlalchemy_iris/intersystems/cursor.py +0 -17
  13. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/LICENSE +0 -0
  14. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_BufferReader.py +0 -0
  15. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_BufferWriter.py +0 -0
  16. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_ConnectionInformation.py +0 -0
  17. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_ConnectionParameters.py +0 -0
  18. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_Constant.py +0 -0
  19. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_DBList.py +0 -0
  20. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_Device.py +0 -0
  21. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_GatewayContext.py +0 -0
  22. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_GatewayException.py +0 -0
  23. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_GatewayUtility.py +0 -0
  24. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_IRIS.py +0 -0
  25. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_IRISConnection.py +0 -0
  26. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_IRISEmbedded.py +0 -0
  27. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_IRISGlobalNode.py +0 -0
  28. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_IRISGlobalNodeView.py +0 -0
  29. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_IRISIterator.py +0 -0
  30. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_IRISList.py +0 -0
  31. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_IRISNative.py +0 -0
  32. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_IRISOREF.py +0 -0
  33. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_IRISObject.py +0 -0
  34. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_IRISReference.py +0 -0
  35. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_InStream.py +0 -0
  36. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_LegacyIterator.py +0 -0
  37. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_ListItem.py +0 -0
  38. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_ListReader.py +0 -0
  39. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_ListWriter.py +0 -0
  40. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_LogFileStream.py +0 -0
  41. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_MessageHeader.py +0 -0
  42. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_OutStream.py +0 -0
  43. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_PrintStream.py +0 -0
  44. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_PythonGateway.py +0 -0
  45. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/_SharedMemorySocket.py +0 -0
  46. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/__init__.py +0 -0
  47. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/__main__.py +0 -0
  48. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/dbapi/_Column.py +0 -0
  49. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/dbapi/_DBAPI.py +0 -0
  50. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/dbapi/_Descriptor.py +0 -0
  51. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/dbapi/_IRISStream.py +0 -0
  52. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/dbapi/_Message.py +0 -0
  53. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/dbapi/_Parameter.py +0 -0
  54. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/dbapi/_ParameterCollection.py +0 -0
  55. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/dbapi/_ResultSetRow.py +0 -0
  56. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/dbapi/_SQLType.py +0 -0
  57. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/dbapi/__init__.py +0 -0
  58. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/dbapi/preparser/_PreParser.py +0 -0
  59. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/dbapi/preparser/_Scanner.py +0 -0
  60. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/dbapi/preparser/_Token.py +0 -0
  61. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/dbapi/preparser/_TokenList.py +0 -0
  62. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/dbapi/preparser/__init__.py +0 -0
  63. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/pex/_BusinessHost.py +0 -0
  64. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/pex/_BusinessOperation.py +0 -0
  65. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/pex/_BusinessProcess.py +0 -0
  66. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/pex/_BusinessService.py +0 -0
  67. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/pex/_Common.py +0 -0
  68. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/pex/_Director.py +0 -0
  69. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/pex/_IRISBusinessOperation.py +0 -0
  70. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/pex/_IRISBusinessService.py +0 -0
  71. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/pex/_IRISInboundAdapter.py +0 -0
  72. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/pex/_IRISOutboundAdapter.py +0 -0
  73. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/pex/_InboundAdapter.py +0 -0
  74. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/pex/_Message.py +0 -0
  75. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/pex/_OutboundAdapter.py +0 -0
  76. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/intersystems_iris/pex/__init__.py +0 -0
  77. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/irisnative/_IRISNative.py +0 -0
  78. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/irisnative/__init__.py +0 -0
  79. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/setup.py +0 -0
  80. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/sqlalchemy_iris/__init__.py +0 -0
  81. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/sqlalchemy_iris/alembic.py +0 -0
  82. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/sqlalchemy_iris/embedded.py +0 -0
  83. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/sqlalchemy_iris/information_schema.py +0 -0
  84. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/sqlalchemy_iris/iris.py +0 -0
  85. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/sqlalchemy_iris/irisasync.py +0 -0
  86. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/sqlalchemy_iris/provision.py +0 -0
  87. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/sqlalchemy_iris/types.py +0 -0
  88. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/sqlalchemy_iris.egg-info/dependency_links.txt +0 -0
  89. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/sqlalchemy_iris.egg-info/entry_points.txt +0 -0
  90. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/sqlalchemy_iris.egg-info/requires.txt +0 -0
  91. {sqlalchemy_iris-0.17.0 → sqlalchemy_iris-0.17.1}/sqlalchemy_iris.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: sqlalchemy-iris
3
- Version: 0.17.0
3
+ Version: 0.17.1
4
4
  Summary: InterSystems IRIS for SQLAlchemy
5
5
  Home-page: https://github.com/caretdev/sqlalchemy-iris
6
6
  Maintainer: CaretDev
@@ -25,6 +25,7 @@ License-File: LICENSE
25
25
  Requires-Dist: SQLAlchemy>=1.3
26
26
  Provides-Extra: intersystems
27
27
  Requires-Dist: intersystems-irispython==5.1.0; extra == "intersystems"
28
+ Dynamic: license-file
28
29
  Dynamic: requires-dist
29
30
 
30
31
  sqlalchemy-iris
@@ -103,6 +104,60 @@ docker run -d --name iris \
103
104
  intersystemsdc/iris-community:preview
104
105
  ```
105
106
 
107
+ Examples
108
+ ===
109
+
110
+ IRISVector
111
+ ---
112
+
113
+ ```python
114
+ from sqlalchemy import Column, MetaData, Table, select
115
+ from sqlalchemy.sql.sqltypes import Integer, UUID
116
+ from sqlalchemy_iris import IRISVector
117
+ from sqlalchemy import create_engine
118
+ from sqlalchemy.orm import DeclarativeBase
119
+ import uuid
120
+
121
+ DATABASE_URL = "iris://_SYSTEM:SYS@localhost:1972/USER"
122
+ engine = create_engine(DATABASE_URL, echo=False)
123
+
124
+ # Create a table metadata
125
+ metadata = MetaData()
126
+
127
+
128
+ class Base(DeclarativeBase):
129
+ pass
130
+
131
+
132
+ def main():
133
+ demo_table = Table(
134
+ "demo_table",
135
+ metadata,
136
+ Column("id", Integer, primary_key=True, autoincrement=True),
137
+ Column("uuid", UUID),
138
+ Column("embedding", IRISVector(item_type=float, max_items=3)),
139
+ )
140
+
141
+ demo_table.drop(engine, checkfirst=True)
142
+ demo_table.create(engine, checkfirst=True)
143
+ with engine.connect() as conn:
144
+ conn.execute(
145
+ demo_table.insert(),
146
+ [
147
+ {"uuid": uuid.uuid4(), "embedding": [1, 2, 3]},
148
+ {"uuid": uuid.uuid4(), "embedding": [2, 3, 4]},
149
+ ],
150
+ )
151
+ conn.commit()
152
+ result = conn.execute(
153
+ demo_table.select()
154
+ ).fetchall()
155
+ print("result", result)
156
+
157
+
158
+ main()
159
+ ```
160
+
106
161
  _Port 1972 is used for binary communication (this driver, xDBC and so on), and 52773 is for web (Management Portal, IRIS based web-applications and API's)._
107
162
 
108
163
  The System Management Portal is available by URL: `http://localhost:52773/csp/sys/UtilHome.csp`
@@ -74,6 +74,60 @@ docker run -d --name iris \
74
74
  intersystemsdc/iris-community:preview
75
75
  ```
76
76
 
77
+ Examples
78
+ ===
79
+
80
+ IRISVector
81
+ ---
82
+
83
+ ```python
84
+ from sqlalchemy import Column, MetaData, Table, select
85
+ from sqlalchemy.sql.sqltypes import Integer, UUID
86
+ from sqlalchemy_iris import IRISVector
87
+ from sqlalchemy import create_engine
88
+ from sqlalchemy.orm import DeclarativeBase
89
+ import uuid
90
+
91
+ DATABASE_URL = "iris://_SYSTEM:SYS@localhost:1972/USER"
92
+ engine = create_engine(DATABASE_URL, echo=False)
93
+
94
+ # Create a table metadata
95
+ metadata = MetaData()
96
+
97
+
98
+ class Base(DeclarativeBase):
99
+ pass
100
+
101
+
102
+ def main():
103
+ demo_table = Table(
104
+ "demo_table",
105
+ metadata,
106
+ Column("id", Integer, primary_key=True, autoincrement=True),
107
+ Column("uuid", UUID),
108
+ Column("embedding", IRISVector(item_type=float, max_items=3)),
109
+ )
110
+
111
+ demo_table.drop(engine, checkfirst=True)
112
+ demo_table.create(engine, checkfirst=True)
113
+ with engine.connect() as conn:
114
+ conn.execute(
115
+ demo_table.insert(),
116
+ [
117
+ {"uuid": uuid.uuid4(), "embedding": [1, 2, 3]},
118
+ {"uuid": uuid.uuid4(), "embedding": [2, 3, 4]},
119
+ ],
120
+ )
121
+ conn.commit()
122
+ result = conn.execute(
123
+ demo_table.select()
124
+ ).fetchall()
125
+ print("result", result)
126
+
127
+
128
+ main()
129
+ ```
130
+
77
131
  _Port 1972 is used for binary communication (this driver, xDBC and so on), and 52773 is for web (Management Portal, IRIS based web-applications and API's)._
78
132
 
79
133
  The System Management Portal is available by URL: `http://localhost:52773/csp/sys/UtilHome.csp`
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = sqlalchemy-iris
3
- version = 0.17.0
3
+ version = 0.17.1
4
4
  description = InterSystems IRIS for SQLAlchemy
5
5
  long_description = file: README.md
6
6
  url = https://github.com/caretdev/sqlalchemy-iris
@@ -33,7 +33,7 @@ intersystems =
33
33
  intersystems-irispython==5.1.0
34
34
 
35
35
  [tool:pytest]
36
- addopts = --tb native -v -r fxX --maxfail=25 -p no:warnings
36
+ addopts = --tb native -v -r fxX -p no:warnings
37
37
 
38
38
  [db]
39
39
  default = iris://_SYSTEM:SYS@localhost:1972/USER
@@ -774,6 +774,9 @@ class IRISTypeCompiler(compiler.GenericTypeCompiler):
774
774
  def visit_LONGVARBINARY(self, type_, **kw):
775
775
  return "LONGVARBINARY"
776
776
 
777
+ def visit_LONGVARCHAR(self, type_, **kw):
778
+ return "LONGVARCHAR"
779
+
777
780
  def visit_DOUBLE(self, type_, **kw):
778
781
  return "DOUBLE"
779
782
 
@@ -971,11 +974,9 @@ There are no access to %Dictionary, may be required for some advanced features,
971
974
 
972
975
  def _get_option(self, connection, option):
973
976
  with connection.cursor() as cursor:
974
- cursor.execute("SELECT %SYSTEM_SQL.Util_GetOption(?)", option)
977
+ cursor.execute("SELECT %SYSTEM_SQL.Util_GetOption(?)", (option, ))
975
978
  row = cursor.fetchone()
976
- if row:
977
- return row[0]
978
- return None
979
+ return row[0] if row else None
979
980
 
980
981
  def _set_option(self, connection, option, value):
981
982
  with connection.cursor() as cursor:
@@ -1091,10 +1092,7 @@ There are no access to %Dictionary, may be required for some advanced features,
1091
1092
  if query.endswith(";"):
1092
1093
  query = query[:-1]
1093
1094
  self._debug(query, params)
1094
- try:
1095
- cursor.execute(query, params)
1096
- except Exception as ex:
1097
- raise ex
1095
+ cursor.execute(query, params)
1098
1096
 
1099
1097
  def do_executemany(self, cursor, query, params, context=None):
1100
1098
  if query.endswith(";"):
@@ -1,12 +1,11 @@
1
1
  import re
2
- import pkg_resources
2
+ from typing import Any
3
3
  from ..base import IRISDialect
4
- from sqlalchemy import text, util
5
4
  from ..base import IRISExecutionContext
6
5
  from . import dbapi
7
- from .dbapi import connect, Cursor
8
- from .cursor import InterSystemsCursorFetchStrategy
6
+ from .dbapi import connect
9
7
  from .dbapi import IntegrityError, OperationalError, DatabaseError
8
+ from sqlalchemy.engine.cursor import CursorFetchStrategy
10
9
 
11
10
 
12
11
  def remap_exception(func):
@@ -20,7 +19,7 @@ def remap_exception(func):
20
19
  except RuntimeError as ex:
21
20
  # [SQLCODE: <-119>:...
22
21
  message = ex.args[0]
23
- if '<LIST ERROR>' in message:
22
+ if "<LIST ERROR>" in message:
24
23
  # just random error happens in the driver, try again
25
24
  continue
26
25
  sqlcode = re.findall(r"^\[SQLCODE: <(-\d+)>:", message)
@@ -28,27 +27,34 @@ def remap_exception(func):
28
27
  raise Exception(message)
29
28
  sqlcode = int(sqlcode[0])
30
29
  if abs(sqlcode) in [108, 119, 121, 122]:
31
- raise IntegrityError(message)
30
+ raise IntegrityError(sqlcode, message)
32
31
  if abs(sqlcode) in [1, 12]:
33
- raise OperationalError(message)
34
- raise DatabaseError(message)
32
+ raise OperationalError(sqlcode, message)
33
+ raise DatabaseError(sqlcode, message)
35
34
 
36
35
  return wrapper
37
36
 
38
37
 
38
+ class InterSystemsCursorFetchStrategy(CursorFetchStrategy):
39
+
40
+ def fetchone(
41
+ self,
42
+ result,
43
+ dbapi_cursor,
44
+ hard_close: bool = False,
45
+ ) -> Any:
46
+ row = dbapi_cursor.fetchone()
47
+ return tuple(row) if row else None
48
+
49
+
39
50
  class InterSystemsExecutionContext(IRISExecutionContext):
40
51
  cursor_fetch_strategy = InterSystemsCursorFetchStrategy()
41
52
 
42
- def create_cursor(self):
43
- cursor = self._dbapi_connection.cursor()
44
- cursor.sqlcode = 0
45
- return cursor
46
-
47
53
 
48
54
  class IRISDialect_intersystems(IRISDialect):
49
55
  driver = "intersystems"
50
56
 
51
- execution_ctx_cls = InterSystemsExecutionContext
57
+ # execution_ctx_cls = InterSystemsExecutionContext
52
58
 
53
59
  supports_statement_cache = True
54
60
 
@@ -62,6 +68,8 @@ class IRISDialect_intersystems(IRISDialect):
62
68
 
63
69
  logfile = None
64
70
 
71
+ server_version = None
72
+
65
73
  def __init__(self, logfile: str = None, **kwargs):
66
74
  self.logfile = logfile
67
75
  IRISDialect.__init__(self, **kwargs)
@@ -115,27 +123,25 @@ class IRISDialect_intersystems(IRISDialect):
115
123
 
116
124
  return ([], opts)
117
125
 
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("."),
126
+ def on_connect(self):
127
+ super_ = super().on_connect()
128
+
129
+ def on_connect(conn):
130
+ if super_ is not None:
131
+ super_(conn)
132
+
133
+ server_version = dbapi.createIRIS(conn).classMethodValue(
134
+ "%SYSTEM.Version", "GetNumber"
135
+ )
136
+ server_version = server_version.split(".")
137
+ self.server_version = tuple(
138
+ [int("".join(filter(str.isdigit, v))) for v in server_version]
127
139
  )
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
140
+
141
+ return on_connect
142
+
143
+ def _get_server_version_info(self, connection):
144
+ return self.server_version
139
145
 
140
146
  def set_isolation_level(self, connection, level_str):
141
147
  if level_str == "AUTOCOMMIT":
@@ -147,6 +153,7 @@ class IRISDialect_intersystems(IRISDialect):
147
153
  with connection.cursor() as cursor:
148
154
  cursor.execute("SET TRANSACTION ISOLATION LEVEL " + level_str)
149
155
 
156
+ """
150
157
  @remap_exception
151
158
  def do_execute(self, cursor, query, params, context=None):
152
159
  if query.endswith(";"):
@@ -163,5 +170,6 @@ class IRISDialect_intersystems(IRISDialect):
163
170
  params = [param[0] if len(param) else None for param in params]
164
171
  cursor.executemany(query, params)
165
172
 
173
+ """
166
174
 
167
175
  dialect = IRISDialect_intersystems
@@ -15,6 +15,10 @@ def connect(*args, **kwargs):
15
15
  return iris.connect(*args, **kwargs)
16
16
 
17
17
 
18
+ def createIRIS(*args, **kwargs):
19
+ return iris.createIRIS(*args, **kwargs)
20
+
21
+
18
22
  # globals
19
23
  apilevel = "2.0"
20
24
  threadsafety = 0
@@ -960,8 +960,8 @@ class Requirements(SuiteRequirements, AlembicRequirements):
960
960
  literal string, e.g. via the TypeEngine.literal_processor() method.
961
961
 
962
962
  """
963
-
964
- return exclusions.open()
963
+ # works stable only on Community driver
964
+ return self.community_driver
965
965
 
966
966
  @property
967
967
  def datetime(self):
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: sqlalchemy-iris
3
- Version: 0.17.0
3
+ Version: 0.17.1
4
4
  Summary: InterSystems IRIS for SQLAlchemy
5
5
  Home-page: https://github.com/caretdev/sqlalchemy-iris
6
6
  Maintainer: CaretDev
@@ -25,6 +25,7 @@ License-File: LICENSE
25
25
  Requires-Dist: SQLAlchemy>=1.3
26
26
  Provides-Extra: intersystems
27
27
  Requires-Dist: intersystems-irispython==5.1.0; extra == "intersystems"
28
+ Dynamic: license-file
28
29
  Dynamic: requires-dist
29
30
 
30
31
  sqlalchemy-iris
@@ -103,6 +104,60 @@ docker run -d --name iris \
103
104
  intersystemsdc/iris-community:preview
104
105
  ```
105
106
 
107
+ Examples
108
+ ===
109
+
110
+ IRISVector
111
+ ---
112
+
113
+ ```python
114
+ from sqlalchemy import Column, MetaData, Table, select
115
+ from sqlalchemy.sql.sqltypes import Integer, UUID
116
+ from sqlalchemy_iris import IRISVector
117
+ from sqlalchemy import create_engine
118
+ from sqlalchemy.orm import DeclarativeBase
119
+ import uuid
120
+
121
+ DATABASE_URL = "iris://_SYSTEM:SYS@localhost:1972/USER"
122
+ engine = create_engine(DATABASE_URL, echo=False)
123
+
124
+ # Create a table metadata
125
+ metadata = MetaData()
126
+
127
+
128
+ class Base(DeclarativeBase):
129
+ pass
130
+
131
+
132
+ def main():
133
+ demo_table = Table(
134
+ "demo_table",
135
+ metadata,
136
+ Column("id", Integer, primary_key=True, autoincrement=True),
137
+ Column("uuid", UUID),
138
+ Column("embedding", IRISVector(item_type=float, max_items=3)),
139
+ )
140
+
141
+ demo_table.drop(engine, checkfirst=True)
142
+ demo_table.create(engine, checkfirst=True)
143
+ with engine.connect() as conn:
144
+ conn.execute(
145
+ demo_table.insert(),
146
+ [
147
+ {"uuid": uuid.uuid4(), "embedding": [1, 2, 3]},
148
+ {"uuid": uuid.uuid4(), "embedding": [2, 3, 4]},
149
+ ],
150
+ )
151
+ conn.commit()
152
+ result = conn.execute(
153
+ demo_table.select()
154
+ ).fetchall()
155
+ print("result", result)
156
+
157
+
158
+ main()
159
+ ```
160
+
106
161
  _Port 1972 is used for binary communication (this driver, xDBC and so on), and 52773 is for web (Management Portal, IRIS based web-applications and API's)._
107
162
 
108
163
  The System Management Portal is available by URL: `http://localhost:52773/csp/sys/UtilHome.csp`
@@ -84,7 +84,6 @@ sqlalchemy_iris.egg-info/entry_points.txt
84
84
  sqlalchemy_iris.egg-info/requires.txt
85
85
  sqlalchemy_iris.egg-info/top_level.txt
86
86
  sqlalchemy_iris/intersystems/__init__.py
87
- sqlalchemy_iris/intersystems/cursor.py
88
87
  sqlalchemy_iris/intersystems/dbapi.py
89
88
  tests/test_alembic.py
90
89
  tests/test_suite.py
@@ -1,3 +1,6 @@
1
+ from sqlalchemy_iris import LONGVARCHAR
2
+
3
+
1
4
  try:
2
5
  import alembic # noqa
3
6
  except: # noqa
@@ -93,14 +96,18 @@ else:
93
96
  @classmethod
94
97
  def insert_data(cls, connection):
95
98
  connection.execute(
96
- text(
97
- """
98
- insert into tab (col) values
99
- ('some data 1'),
100
- ('some data 2'),
101
- ('some data 3')
102
- """
103
- )
99
+ cls.tables.tab.insert(),
100
+ [
101
+ {
102
+ "col": "some data 1",
103
+ },
104
+ {
105
+ "col": "some data 2",
106
+ },
107
+ {
108
+ "col": "some data 3",
109
+ },
110
+ ],
104
111
  )
105
112
 
106
113
  def test_str_to_blob(self, connection, ops_context):
@@ -124,3 +131,29 @@ else:
124
131
  assert col["name"] == "col"
125
132
  assert isinstance(col["type"], LONGVARBINARY)
126
133
  assert not col["nullable"]
134
+
135
+ class TestIRISLONGVARCHAR(TestBase):
136
+
137
+ @fixture
138
+ def tables(self, connection):
139
+ self.meta = MetaData()
140
+ self.tbl = Table(
141
+ "longvarbinary_test",
142
+ self.meta,
143
+ Column("id", Integer, primary_key=True),
144
+ Column("data", LONGVARCHAR),
145
+ )
146
+ self.meta.create_all(connection)
147
+ yield
148
+ self.meta.drop_all(connection)
149
+
150
+ def test_longvarchar(self, connection, tables):
151
+ connection.execute(
152
+ self.tbl.insert(),
153
+ [
154
+ {"data": "test data"},
155
+ {"data": "more test data"},
156
+ ],
157
+ )
158
+ result = connection.execute(self.tbl.select()).fetchall()
159
+ assert result == [(1, "test data"), (2, "more test data")]
@@ -22,7 +22,6 @@ from sqlalchemy_iris import INTEGER
22
22
  from sqlalchemy_iris import IRISListBuild
23
23
  from sqlalchemy_iris import IRISVector
24
24
  from sqlalchemy.exc import DatabaseError
25
- from sqlalchemy.testing.config import requirements
26
25
 
27
26
  import pytest
28
27
 
@@ -1,17 +0,0 @@
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
-