Skip to content

Commit 59c9e09

Browse files
committed
many updates
1 parent 0d46f43 commit 59c9e09

File tree

6 files changed

+117
-9
lines changed

6 files changed

+117
-9
lines changed

requirements-iris.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
https://github.com/intersystems-community/intersystems-irispython/releases/download/3.7.9/intersystems_iris-3.7.9-py3-none-any.whl
1+
https://github.com/intersystems-community/intersystems-irispython/releases/download/3.9.0/intersystems_iris-3.9.0-py3-none-any.whl

sqlalchemy_iris/base.py

+62-3
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,20 @@ def visit_drop_schema(self, drop, **kw):
653653
def visit_check_constraint(self, constraint, **kw):
654654
pass
655655

656+
def create_table_constraints(self, table, **kw):
657+
description = ""
658+
comment = table.comment
659+
if comment:
660+
# hack to keep \r, kind of
661+
comment = comment.replace('\r', '\n\t')
662+
literal = self.sql_compiler.render_literal_value(comment, sqltypes.String())
663+
description = "%DESCRIPTION " + literal
664+
665+
constraints = super().create_table_constraints(table, **kw)
666+
if constraints and description:
667+
description = ", \n\t" + description
668+
return constraints + description
669+
656670
def visit_add_constraint(self, create, **kw):
657671
if isinstance(create.element, schema.CheckConstraint):
658672
raise exc.CompileError("Can't add CHECK constraint")
@@ -701,6 +715,7 @@ def get_column_specification(self, column, **kwargs):
701715

702716
comment = column.comment
703717
if comment is not None:
718+
comment = comment.replace('\r', '\n\t')
704719
literal = self.sql_compiler.render_literal_value(comment, sqltypes.String())
705720
colspec.append("%DESCRIPTION " + literal)
706721

@@ -883,6 +898,12 @@ class IRISDialect(default.DefaultDialect):
883898
type_compiler = IRISTypeCompiler
884899
execution_ctx_cls = IRISExecutionContext
885900

901+
insert_returning = True
902+
insert_executemany_returning = True
903+
insert_executemany_returning_sort_by_parameter_order = True
904+
update_executemany_returning = False
905+
delete_executemany_returning = False
906+
886907
construct_arguments = [
887908
(schema.Index, {"include": None}),
888909
]
@@ -1105,6 +1126,38 @@ def get_schema(self, schema=None):
11051126
return "SQLUser"
11061127
return schema
11071128

1129+
@reflection.cache
1130+
def get_table_options(self, connection, table_name, schema=None, **kw):
1131+
if not self.has_table(connection=connection, table_name=table_name, schema=schema):
1132+
raise exc.NoSuchTableError(
1133+
f"{schema}.{table_name}" if schema else table_name
1134+
) from None
1135+
return {}
1136+
1137+
@reflection.cache
1138+
def get_table_comment(self, connection, table_name, schema=None, **kw):
1139+
if not self.has_table(connection=connection, table_name=table_name, schema=schema):
1140+
raise exc.NoSuchTableError(
1141+
f"{schema}.{table_name}" if schema else table_name
1142+
) from None
1143+
1144+
tables = ischema.tables
1145+
schema_name = self.get_schema(schema)
1146+
1147+
s = sql.select(tables.c.description).where(
1148+
sql.and_(
1149+
tables.c.table_schema == str(schema_name),
1150+
tables.c.table_name == str(table_name),
1151+
)
1152+
)
1153+
comment = connection.execute(s).scalar()
1154+
if comment:
1155+
# make it as \r
1156+
comment = comment.replace(' \t\t\t\t', '\r')
1157+
# restore \n
1158+
comment = comment.replace(' \t\t\t', '\n')
1159+
return {"text": comment}
1160+
11081161
@reflection.cache
11091162
def get_schema_names(self, connection, **kw):
11101163
s = sql.select(ischema.schemata.c.schema_name).order_by(
@@ -1131,7 +1184,7 @@ def get_table_names(self, connection, schema=None, **kw):
11311184
return table_names
11321185

11331186
@reflection.cache
1134-
def get_temp_table_names(self, connection, dblink=None, **kw):
1187+
def get_temp_table_names(self, connection, **kw):
11351188
tables = ischema.tables
11361189
s = (
11371190
sql.select(tables.c.table_name)
@@ -1598,6 +1651,7 @@ def get_multi_columns(
15981651
columns.c.column_default,
15991652
columns.c.collation_name,
16001653
columns.c.auto_increment,
1654+
columns.c.description,
16011655
)
16021656
.select_from(columns)
16031657
.where(
@@ -1650,7 +1704,12 @@ def get_multi_columns(
16501704
sqlComputeCode = row[property.c.SqlComputeCode]
16511705
calculated = row[property.c.Calculated]
16521706
transient = row[property.c.Transient]
1653-
# description = row[columns.c.description]
1707+
comment = row[columns.c.description]
1708+
if comment:
1709+
# make it as \r
1710+
comment = comment.replace(' \t\t\t\t', '\r')
1711+
# restore \n
1712+
comment = comment.replace(' \t\t\t', '\n')
16541713

16551714
coltype = self.ischema_names.get(type_, None)
16561715

@@ -1696,7 +1755,7 @@ def get_multi_columns(
16961755
"nullable": nullable,
16971756
"default": default,
16981757
"autoincrement": autoincrement,
1699-
# "comment": description,
1758+
"comment": comment,
17001759
}
17011760
if sqlComputeCode and "set {*} = " in sqlComputeCode.lower():
17021761
sqltext = sqlComputeCode

sqlalchemy_iris/information_schema.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ def process_result_value(self, value, dialect):
4444
Column("TABLE_NAME", String, key="table_name"),
4545
Column("TABLE_TYPE", String, key="table_type"),
4646
Column("CLASSNAME", String, key="classname"),
47+
Column("DESCRIPTION", String, key="description"),
4748
schema="INFORMATION_SCHEMA",
4849
)
4950

@@ -69,7 +70,7 @@ def process_result_value(self, value, dialect):
6970
Column("AUTO_INCREMENT", YESNO, key="auto_increment"),
7071
Column("UNIQUE_COLUMN", YESNO, key="unique_column"),
7172
Column("PRIMARY_KEY", YESNO, key="primary_key"),
72-
Column("DESCIPTION", String, key="desciption"),
73+
Column("DESCRIPTION", String, key="description"),
7374
schema="INFORMATION_SCHEMA",
7475
)
7576
property_definition = Table(

sqlalchemy_iris/requirements.py

+16
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,22 @@ def datetime_historic(self):
5858

5959
return exclusions.open()
6060

61+
@property
62+
def reflect_table_options(self):
63+
return exclusions.open()
64+
65+
@property
66+
def comment_reflection(self):
67+
return exclusions.open()
68+
69+
@property
70+
def insert_returning(self):
71+
return exclusions.open()
72+
73+
@property
74+
def unusual_column_name_characters(self):
75+
return exclusions.open()
76+
6177
@property
6278
def computed_columns(self):
6379
"Supports computed columns"

tests/conftest.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from sqlalchemy.dialects import registry
22
import pytest
33
import time
4+
import os
45

56
from sqlalchemy.testing.plugin.plugin_base import pre
67

@@ -46,6 +47,7 @@ def start_container(opt, file_config):
4647
username="sqlalchemy",
4748
password="sqlalchemy",
4849
namespace="TEST",
50+
license_key=os.path.expanduser("~/iris.key") if "community" not in opt.container else None,
4951
)
5052
iris.start()
5153
print("dburi:", iris.get_connection_url())
@@ -54,6 +56,6 @@ def start_container(opt, file_config):
5456

5557
def pytest_unconfigure(config):
5658
global iris
57-
if iris:
58-
print("Stopping IRIS container")
59+
if iris and iris._container:
60+
print("Stopping IRIS container", iris)
5961
iris.stop()

tests/test_suite.py

+32-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
from sqlalchemy.testing.suite import FetchLimitOffsetTest as _FetchLimitOffsetTest
44
from sqlalchemy.testing.suite import CompoundSelectTest as _CompoundSelectTest
5+
from sqlalchemy.testing.suite import TableDDLTest as _TableDDLTest
6+
from sqlalchemy.testing.suite import FutureTableDDLTest as _FutureTableDDLTest
57
from sqlalchemy.testing.suite import CTETest as _CTETest
68
from sqlalchemy.testing.suite import DifficultParametersTest as _DifficultParametersTest
79
from sqlalchemy.testing import fixtures
@@ -63,9 +65,19 @@ def test_select_recursive_round_trip(self):
6365
pass
6466

6567

66-
@pytest.mark.skip()
6768
class DifficultParametersTest(_DifficultParametersTest):
68-
pass
69+
70+
tough_parameters = _DifficultParametersTest.tough_parameters
71+
72+
@tough_parameters
73+
def test_round_trip_same_named_column(
74+
self, paramname, connection, metadata
75+
):
76+
if paramname == 'dot.s':
77+
# not supported
78+
pytest.skip()
79+
return
80+
super().test_round_trip_same_named_column(paramname, connection, metadata)
6981

7082

7183
class FetchLimitOffsetTest(_FetchLimitOffsetTest):
@@ -486,3 +498,21 @@ def test_concat_func(self):
486498
("sometestdata",),
487499
],
488500
)
501+
502+
503+
class TableDDLTest(_TableDDLTest):
504+
# IRIS does not want to update comments on the fly
505+
def test_add_table_comment(self, connection):
506+
pass
507+
508+
def test_drop_table_comment(self, connection):
509+
pass
510+
511+
512+
class FutureTableDDLTest(_FutureTableDDLTest):
513+
# IRIS does not want to update comments on the fly
514+
def test_add_table_comment(self, connection):
515+
pass
516+
517+
def test_drop_table_comment(self, connection):
518+
pass

0 commit comments

Comments
 (0)