sqlalchemy-iris 0.10.0b2__py3-none-any.whl → 0.10.1__py3-none-any.whl

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.
@@ -84,8 +84,14 @@ class _Parameter(intersystems_iris.dbapi._Descriptor._Descriptor):
84
84
  float: lambda v : v,
85
85
  decimal.Decimal: lambda v : v,
86
86
  }
87
- func = _set_switcher[type(self.__value)] if type(self.__value) in _set_switcher else (lambda v : str(v))
88
- value = func(self.__value)
87
+ func = None
88
+ if issubclass(type(self.__value), enum.Enum):
89
+ value = self.__value.value
90
+ elif type(self.__value) in _set_switcher:
91
+ func = _set_switcher[type(self.__value)]
92
+ value = func(self.__value)
93
+ else:
94
+ value = str(self.__value)
89
95
  if self.mode == ParameterMode.REPLACED_LITERAL:
90
96
  if isinstance(value, str) and value.isdigit():
91
97
  value = int(value)
@@ -88,7 +88,7 @@ class _ResultSetRow:
88
88
  SQLType.TYPE_DATE: None,
89
89
  SQLType.TYPE_TIME: None,
90
90
  SQLType.TYPE_TIMESTAMP: None,
91
- SQLType.VARBINARY: None,
91
+ SQLType.VARBINARY: bytes,
92
92
  SQLType.VARCHAR: str,
93
93
  SQLType.WCHAR: None,
94
94
  SQLType.WLONGVARCHAR: None,
@@ -165,6 +165,8 @@ class _ResultSetRow:
165
165
  pass
166
166
  elif item is None:
167
167
  pass
168
+ elif value_type is bytes:
169
+ item = bytes(map(ord, item))
168
170
  elif issubclass(value_type, IRISStream):
169
171
  stream = value_type(self._connection, item)
170
172
  item = stream.fetch()
@@ -1,25 +1,39 @@
1
1
  import logging
2
+ import re
2
3
 
3
4
  from typing import Optional
5
+ from typing import Any
4
6
 
5
7
  from sqlalchemy.ext.compiler import compiles
6
8
  from sqlalchemy.sql.base import Executable
7
9
  from sqlalchemy.sql.elements import ClauseElement
10
+ from sqlalchemy.sql.type_api import TypeEngine
11
+ from sqlalchemy.sql import table
12
+ from sqlalchemy import types
8
13
 
9
14
  from alembic.ddl import DefaultImpl
10
15
  from alembic.ddl.base import ColumnNullable
11
16
  from alembic.ddl.base import ColumnType
12
17
  from alembic.ddl.base import ColumnName
18
+ from alembic.ddl.base import AddColumn
19
+ from alembic.ddl.base import DropColumn
13
20
  from alembic.ddl.base import Column
14
21
  from alembic.ddl.base import alter_table
15
22
  from alembic.ddl.base import alter_column
23
+ from alembic.ddl.base import drop_column
16
24
  from alembic.ddl.base import format_type
17
25
  from alembic.ddl.base import format_column_name
18
-
19
26
  from .base import IRISDDLCompiler
20
27
 
21
28
  log = logging.getLogger(__name__)
22
29
 
30
+ # IRIS Interprets these types as %Streams, and no direct type change is available
31
+ _as_stream = [
32
+ types.LargeBinary,
33
+ types.BLOB,
34
+ types.CLOB,
35
+ ]
36
+
23
37
 
24
38
  class IRISImpl(DefaultImpl):
25
39
  __dialect__ = "iris"
@@ -54,28 +68,71 @@ class IRISImpl(DefaultImpl):
54
68
  ):
55
69
  return False
56
70
 
57
- return super().compare_server_default(
58
- inspector_column,
59
- metadata_column,
60
- rendered_metadata_default,
61
- rendered_inspector_default,
62
- )
71
+ if rendered_metadata_default is not None:
72
+ rendered_metadata_default = re.sub(
73
+ r"[\(\) \"\']", "", rendered_metadata_default
74
+ )
75
+
76
+ if rendered_inspector_default is not None:
77
+ rendered_inspector_default = re.sub(
78
+ r"[\(\) \"\']", "", rendered_inspector_default
79
+ )
80
+
81
+ return rendered_inspector_default != rendered_metadata_default
63
82
 
64
- def drop_column(
83
+ def alter_column(
65
84
  self,
66
85
  table_name: str,
67
- column: Column,
86
+ column_name: str,
87
+ type_: Optional[TypeEngine] = None,
88
+ existing_type: Optional[TypeEngine] = None,
68
89
  schema: Optional[str] = None,
69
- **kw,
90
+ name: Optional[str] = None,
91
+ **kw: Any,
70
92
  ) -> None:
71
- column_name = column.name
72
- fkeys = self.dialect.get_foreign_keys(self.connection, table_name, schema)
73
- fkey = [
74
- fkey["name"] for fkey in fkeys if column_name in fkey["constrained_columns"]
75
- ]
76
- if len(fkey) == 1:
77
- self._exec(_ExecDropForeignKey(table_name, fkey[0], schema))
78
- super().drop_column(table_name, column, schema, **kw)
93
+ if existing_type.__class__ not in _as_stream and type_.__class__ in _as_stream:
94
+ """
95
+ To change column type to %Stream
96
+ * rename the column with a new name with suffix `__superset_tmp`
97
+ * create a new column with the old name
98
+ * copy data from an old column to new column
99
+ * drop old column
100
+ * fix missing parameters, such as nullable
101
+ """
102
+ tmp_column = f"{column_name}__superset_tmp"
103
+ self._exec(ColumnName(table_name, column_name, tmp_column, schema=schema))
104
+ new_kw = {}
105
+ self._exec(
106
+ AddColumn(
107
+ table_name,
108
+ Column(column_name, type_=type_, **new_kw),
109
+ schema=schema,
110
+ )
111
+ )
112
+ tab = table(
113
+ table_name,
114
+ Column(column_name, key="new_col"),
115
+ Column(tmp_column, key="old_col"),
116
+ schema=schema,
117
+ )
118
+ self._exec(tab.update().values({tab.c.new_col: tab.c.old_col}))
119
+ self._exec(DropColumn(table_name, Column(tmp_column), schema=schema))
120
+ new_kw = {}
121
+ for k in ["server_default", "nullable", "autoincrement"]:
122
+ if f"existing_{k}" in kw:
123
+ new_kw[k] = kw[f"existing_{k}"]
124
+ return super().alter_column(
125
+ table_name, column_name, schema=schema, name=name, **new_kw
126
+ )
127
+ return super().alter_column(
128
+ table_name,
129
+ column_name,
130
+ type_=type_,
131
+ existing_type=existing_type,
132
+ schema=schema,
133
+ name=name,
134
+ **kw,
135
+ )
79
136
 
80
137
 
81
138
  class _ExecDropForeignKey(Executable, ClauseElement):
@@ -126,3 +183,11 @@ def visit_rename_column(element: ColumnName, compiler: IRISDDLCompiler, **kw) ->
126
183
  alter_column(compiler, element.column_name),
127
184
  format_column_name(compiler, element.newname),
128
185
  )
186
+
187
+
188
+ @compiles(DropColumn, "iris")
189
+ def visit_drop_column(element: DropColumn, compiler: IRISDDLCompiler, **kw) -> str:
190
+ return "%s %s CASCADE" % (
191
+ alter_table(compiler, element.table_name, element.schema),
192
+ drop_column(compiler, element.column.name, **kw),
193
+ )
sqlalchemy_iris/base.py CHANGED
@@ -10,6 +10,7 @@ from sqlalchemy.sql import util as sql_util
10
10
  from sqlalchemy.sql import between
11
11
  from sqlalchemy.sql import func
12
12
  from sqlalchemy.sql.functions import ReturnTypeFromArgs
13
+ from sqlalchemy.sql.elements import Null
13
14
  from sqlalchemy.sql import expression
14
15
  from sqlalchemy.sql import schema
15
16
  from sqlalchemy import sql, text
@@ -394,6 +395,12 @@ RESERVED_WORDS = set(
394
395
  class IRISCompiler(sql.compiler.SQLCompiler):
395
396
  """IRIS specific idiosyncrasies"""
396
397
 
398
+ def visit_exists_unary_operator(self, element, operator, within_columns_clause=False, **kw):
399
+ if within_columns_clause:
400
+ return "(SELECT 1 WHERE EXISTS(%s))" % self.process(element.element, **kw)
401
+ else:
402
+ return "EXISTS(%s)" % self.process(element.element, **kw)
403
+
397
404
  def limit_clause(self, select, **kw):
398
405
  return ""
399
406
 
@@ -439,6 +446,22 @@ class IRISCompiler(sql.compiler.SQLCompiler):
439
446
  def visit_is_false_unary_operator(self, element, operator, **kw):
440
447
  return "%s = 0" % self.process(element.element, **kw)
441
448
 
449
+ def visit_is__binary(self, binary, operator, **kw):
450
+ op = "IS" if isinstance(binary.right, Null) else "="
451
+ return "%s %s %s" % (
452
+ self.process(binary.left),
453
+ op,
454
+ self.process(binary.right),
455
+ )
456
+
457
+ def visit_is_not_binary(self, binary, operator, **kw):
458
+ op = "IS NOT" if isinstance(binary.right, Null) else "<>"
459
+ return "%s %s %s" % (
460
+ self.process(binary.left),
461
+ op,
462
+ self.process(binary.right),
463
+ )
464
+
442
465
  def get_select_precolumns(self, select, **kw):
443
466
  text = ""
444
467
  if select._distinct or select._distinct_on:
@@ -556,16 +579,6 @@ class IRISCompiler(sql.compiler.SQLCompiler):
556
579
  else:
557
580
  return ""
558
581
 
559
- def visit_column(self, column, within_columns_clause=False, **kwargs):
560
- text = super().visit_column(
561
- column, within_columns_clause=within_columns_clause, **kwargs
562
- )
563
- if within_columns_clause:
564
- return text
565
- # if isinstance(column.type, sqltypes.Text):
566
- # text = "CONVERT(VARCHAR, %s)" % (text,)
567
- return text
568
-
569
582
  def visit_concat_op_binary(self, binary, operator, **kw):
570
583
  return "STRING(%s, %s)" % (
571
584
  self.process(binary.left, **kw),
@@ -821,6 +834,8 @@ class IRISDialect(default.DefaultDialect):
821
834
 
822
835
  supports_sequences = False
823
836
 
837
+ returns_native_bytes = True
838
+
824
839
  div_is_floordiv = False
825
840
 
826
841
  postfetch_lastrowid = True
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sqlalchemy-iris
3
- Version: 0.10.0b2
3
+ Version: 0.10.1
4
4
  Summary: InterSystems IRIS for SQLAlchemy
5
5
  Home-page: https://github.com/caretdev/sqlalchemy-iris
6
6
  Maintainer: CaretDev
@@ -33,13 +33,13 @@ intersystems_iris/_SharedMemorySocket.py,sha256=2iUaS1FdJNSCUEaE-VT0O_dxF6NRwqZS
33
33
  intersystems_iris/__init__.py,sha256=Tk1tD28LwvF6X3yXQsJFLE1Bc-PR3gUJWcX5UnNYOdY,1773
34
34
  intersystems_iris/__main__.py,sha256=rCtINTfJcADMAsw1ja-MEO7Q-XekrWthYowzWV8xGIQ,218
35
35
  intersystems_iris/dbapi/_Column.py,sha256=VCLHLXs3wuGcUa9w_qy7HBFsuGvhmmI3kGYBagQg59U,2535
36
- intersystems_iris/dbapi/_DBAPI.py,sha256=BOyWi5EiXL1DmgqDfzM9df-tE5sTkqSw4tuFEpk89kg,95597
36
+ intersystems_iris/dbapi/_DBAPI.py,sha256=2kjZM_fYwuQGRJX1stqOuAGgvOq5Q0F5zzZtrboC-do,98080
37
37
  intersystems_iris/dbapi/_Descriptor.py,sha256=IjyITxvjygDrhpk-0lGhdqQPh91SG6nTb1vi-AqyJNI,1391
38
38
  intersystems_iris/dbapi/_IRISStream.py,sha256=Vz3ydS9djxqqp-1F385FHgjjJNosXNpGMu-rkAPJDrs,2113
39
39
  intersystems_iris/dbapi/_Message.py,sha256=jpLG3HZElqp981iNPFW8UNRO3NbHf6poEv6yywX0Ssw,4076
40
- intersystems_iris/dbapi/_Parameter.py,sha256=JqpWCpz_XhLBWpxGYJ6UqE0zdysDO4LxoV7zgdaiXEA,4687
40
+ intersystems_iris/dbapi/_Parameter.py,sha256=EUZhS8qnNqgiOfuayE6LcpN8lBujk0_ZChGkC-v3pXY,4846
41
41
  intersystems_iris/dbapi/_ParameterCollection.py,sha256=ta8nuwHjTbY4V_ouOmNQv4C46u8eA6cdvij9xIWqQuo,5151
42
- intersystems_iris/dbapi/_ResultSetRow.py,sha256=o_lqYAmge8V9KjIWjiWKHUe8ZshgKypFJT6OLIQEjAo,12810
42
+ intersystems_iris/dbapi/_ResultSetRow.py,sha256=tNKCv5P8XhP9zzdPpBGiXYHLKOScITTBGSqtui1TAM0,12910
43
43
  intersystems_iris/dbapi/_SQLType.py,sha256=IlDacXwQzUMWaJ02Zsu2bUfvUC3-5mBx-m6mE0Yp7ts,557
44
44
  intersystems_iris/dbapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
45
  intersystems_iris/dbapi/preparser/_PreParser.py,sha256=024w-s3n_JNsk_ISC8avJMK3QEZE3hSuD0Nr8arJdZw,78828
@@ -68,17 +68,17 @@ iris/irisloader.py,sha256=2ZLM0FlYNStTiZrXuvDcO-V_XZVgmB3R8vesmaqMqYA,4808
68
68
  irisnative/_IRISNative.py,sha256=HQ4nBhc8t8_5OtxdMG-kx1aa-T1znf2I8obZOPLOPzg,665
69
69
  irisnative/__init__.py,sha256=6YmvBLQSURsCPKaNg7LK-xpo4ipDjrlhKuwdfdNb3Kg,341
70
70
  sqlalchemy_iris/__init__.py,sha256=TKZt8fTcW8HDhw5ukl6sPyodH8u185eWYrKPHrJGb3I,992
71
- sqlalchemy_iris/alembic.py,sha256=inxt57Ei0XAmu4p2acRsz4e6HLlJjVJCIcltfh4WTDs,3980
72
- sqlalchemy_iris/base.py,sha256=Qi5VeYLXqJswOoJWTEK0KTqsJygfodj-QjNVVQuPCng,49415
71
+ sqlalchemy_iris/alembic.py,sha256=IhZP6P-whMrXzD8lTCKvIC6EK8hKW88JTNG_U8t2quk,6373
72
+ sqlalchemy_iris/base.py,sha256=8vMpwjF9bDVFT5t1k6G5ZUvAZEf6bfs8pYUmrov9rzM,49924
73
73
  sqlalchemy_iris/embedded.py,sha256=6DbnfcJwYQmHjyvQQ0cN6mV6zbF3AAOJkucww5LypiE,547
74
74
  sqlalchemy_iris/information_schema.py,sha256=Ei1gAHXn4fWpvmUzwf-2hGslU458uQXFt1s0r1NAj2Y,6132
75
75
  sqlalchemy_iris/iris.py,sha256=Of0Ruc9W2c5ll5sjAy1xRo4tf1m0l_ab0vAdacTv3Yw,276
76
76
  sqlalchemy_iris/provision.py,sha256=drorbIgNO770Ws0XiCRXY_sDbQGIy2_zzNK3KYrDetY,198
77
77
  sqlalchemy_iris/requirements.py,sha256=eIV8bcPHOmSrGxzxfqVeLYEdol3MIoXnRQLI9sq32mM,7175
78
78
  sqlalchemy_iris/types.py,sha256=JRQROZyhAuVX0w_hYkuRfJQt9Bxa4ruKfVQrG_s-0Qc,4216
79
- sqlalchemy_iris-0.10.0b2.dist-info/LICENSE,sha256=RQmigqltsLq8lfOBc_KwtL0gkODyUCNpU-0ZiZwGlho,1075
80
- sqlalchemy_iris-0.10.0b2.dist-info/METADATA,sha256=qTGQvDamUBWlLtu-iVnsXBHlndo03lvLdLaZmXSBIi8,2341
81
- sqlalchemy_iris-0.10.0b2.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
82
- sqlalchemy_iris-0.10.0b2.dist-info/entry_points.txt,sha256=w7qS4R3anhoVEC5rzpw1H6gLu41wdZiahfg9bNH0Tio,119
83
- sqlalchemy_iris-0.10.0b2.dist-info/top_level.txt,sha256=mjpHqFjekbB1TWr3xI3o4AqN3Spby-_uqyuSSeBDmuw,50
84
- sqlalchemy_iris-0.10.0b2.dist-info/RECORD,,
79
+ sqlalchemy_iris-0.10.1.dist-info/LICENSE,sha256=RQmigqltsLq8lfOBc_KwtL0gkODyUCNpU-0ZiZwGlho,1075
80
+ sqlalchemy_iris-0.10.1.dist-info/METADATA,sha256=GwyPdB22ABXENbkyfYOQq-AIKHuv7ZdYYmw4pmGbQB0,2339
81
+ sqlalchemy_iris-0.10.1.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
82
+ sqlalchemy_iris-0.10.1.dist-info/entry_points.txt,sha256=w7qS4R3anhoVEC5rzpw1H6gLu41wdZiahfg9bNH0Tio,119
83
+ sqlalchemy_iris-0.10.1.dist-info/top_level.txt,sha256=mjpHqFjekbB1TWr3xI3o4AqN3Spby-_uqyuSSeBDmuw,50
84
+ sqlalchemy_iris-0.10.1.dist-info/RECORD,,