Skip to content

Commit

Permalink
various updates
Browse files Browse the repository at this point in the history
  • Loading branch information
daimor committed Oct 28, 2022
1 parent 437eb7d commit 73c83e9
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 26 deletions.
5 changes: 4 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,12 @@ addopts= --tb native -v -r fxX --maxfail=25 -p no:warnings
python_files=test/*test_*.py

[db]
default=iris+iris://_SYSTEM:SYS@localhost:1972/USER
default=iris://_SYSTEM:SYS@localhost:1972/USER
sqlite=sqlite:///:memory:

[sqla_testing]
requirement_cls=sqlalchemy_iris.requirements:Requirements
profile_file=test/profiles.txt

[flake8]
max-line-length=120
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
dependency_links=dependency_links,
entry_points={
"sqlalchemy.dialects": [
"iris = sqlalchemy_iris:IRISDialect",
"iris = sqlalchemy_iris.iris:IRISDialect_iris",
]
},
)
8 changes: 4 additions & 4 deletions sqlalchemy_iris/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from sqlalchemy.dialects import registry as _registry

from . import base
from . import iris
from .base import IRISDialect
from .iris import IRISDialect_iris

base.dialect = dialect = iris.dialect

_registry.register("iris.iris", "sqlalchemy_iris.iris", "IRISDialect_iris")

__all__ = [
IRISDialect,
IRISDialect_iris,
dialect,
]
55 changes: 49 additions & 6 deletions sqlalchemy_iris/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from sqlalchemy.sql import util as sql_util
from sqlalchemy.sql import between
from sqlalchemy.sql import func
from sqlalchemy import sql
from sqlalchemy import sql, text
from sqlalchemy import util
from sqlalchemy import types as sqltypes

Expand Down Expand Up @@ -393,6 +393,9 @@ def translate_select_structure(self, select_stmt, **kwargs):
for elem in select._order_by_clause.clauses
]

if not _order_by_clauses:
_order_by_clauses = [text('%id')]

limit_clause = self._get_limit_or_fetch(select)
offset_clause = select._offset_clause

Expand Down Expand Up @@ -440,6 +443,44 @@ def visit_drop_schema(self, drop, **kw):
def visit_check_constraint(self, constraint, **kw):
raise exc.CompileError("Check CONSTRAINT not supported")

def get_column_specification(self, column, **kwargs):

colspec = [
self.preparer.format_column(column),
]

if (
column.primary_key
and column is column.table._autoincrement_column
):
colspec.append("SERIAL")
else:
colspec.append(
self.dialect.type_compiler.process(
column.type,
type_expression=column,
identifier_preparer=self.preparer,
)
)

if column.computed is not None:
colspec.append(self.process(column.computed))
default = self.get_column_default_string(column)
if default is not None:
colspec.append("DEFAULT " + default)

if not column.nullable:
colspec.append("NOT NULL")

comment = column.comment
if comment is not None:
literal = self.sql_compiler.render_literal_value(
comment, sqltypes.String()
)
colspec.append("%%DESCRIPTION " + literal)

return " ".join(colspec)


class IRISTypeCompiler(compiler.GenericTypeCompiler):
def visit_boolean(self, type_, **kw):
Expand Down Expand Up @@ -536,11 +577,13 @@ def process(value):


class IRISDialect(default.DefaultDialect):
driver = 'iris'

name = 'iris'

default_schema_name = "SQLUser"

default_paramstyle = "format"
supports_statement_cache = True

supports_native_decimal = True
supports_sane_rowcount = True
Expand All @@ -551,7 +594,6 @@ class IRISDialect(default.DefaultDialect):

supports_sequences = False

supports_statement_cache = False
postfetch_lastrowid = False
non_native_boolean_check_constraint = False
supports_simple_order_by_label = False
Expand Down Expand Up @@ -610,6 +652,7 @@ def _fix_for_params(self, query, params, many=False):

def do_execute(self, cursor, query, params, context=None):
query, params = self._fix_for_params(query, params)
# print('do_execute', query, params)
cursor.execute(query, params)

def do_executemany(self, cursor, query, params, context=None):
Expand Down Expand Up @@ -903,7 +946,7 @@ def get_columns(self, connection, table_name, schema=None, **kw):
):
if charlen == -1:
charlen = None
kwargs["length"] = charlen
kwargs["length"] = int(charlen)
if collation:
kwargs["collation"] = collation
if coltype is None:
Expand All @@ -914,10 +957,10 @@ def get_columns(self, connection, table_name, schema=None, **kw):
coltype = sqltypes.NULLTYPE
else:
if issubclass(coltype, sqltypes.Numeric):
kwargs["precision"] = numericprec
kwargs["precision"] = int(numericprec)

if not issubclass(coltype, sqltypes.Float):
kwargs["scale"] = numericscale
kwargs["scale"] = int(numericscale)

coltype = coltype(**kwargs)

Expand Down
4 changes: 1 addition & 3 deletions sqlalchemy_iris/iris.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@
class IRISDialect_iris(IRISDialect):
driver = "iris"

def create_connect_args(self, url):
opts = dict(url.query)
return ([], opts)
supports_statement_cache = True


dialect = IRISDialect_iris
9 changes: 4 additions & 5 deletions sqlalchemy_iris/requirements.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ def autoincrement_insert(self):
"""target platform generates new surrogate integer primary key values
when insert() is executed, excluding the pk column."""

return exclusions.closed()
return exclusions.open()

@property
def fetch_rows_post_commit(self):
Expand Down Expand Up @@ -367,8 +367,7 @@ def reflects_pk_names(self):
@property
def table_reflection(self):
"""target database has general support for table reflection"""
# return exclusions.open()
return exclusions.closed()
return exclusions.open()

@property
def reflect_tables_no_columns(self):
Expand Down Expand Up @@ -1124,5 +1123,5 @@ def autoincrement_without_sequence(self):
"""If autoincrement=True on a column does not require an explicit
sequence. This should be false only for oracle.
"""
# return exclusions.open()
return exclusions.closed()
return exclusions.open()
# return exclusions.closed()
6 changes: 2 additions & 4 deletions test/conftest.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
from sqlalchemy.dialects import registry
import pytest

registry.register(
"iris.iris", "sqlalchemy_iris", "IRISDialect"
)
registry.register("iris.iris", "sqlalchemy_iris.iris", "IRISDialect_iris")

pytest.register_assert_rewrite("sqlalchemy.testing.assertions")

from sqlalchemy.testing.plugin.pytestplugin import *
from sqlalchemy.testing.plugin.pytestplugin import * # noqa
68 changes: 66 additions & 2 deletions test/test_suite.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
from sqlalchemy.testing.suite.test_reflection import QuotedNameArgumentTest as _QuotedNameArgumentTest
from sqlalchemy.testing.suite import QuotedNameArgumentTest as _QuotedNameArgumentTest
from sqlalchemy.testing.suite import FetchLimitOffsetTest as _FetchLimitOffsetTest
from sqlalchemy.testing.suite import CompoundSelectTest as _CompoundSelectTest
from sqlalchemy.testing import fixtures, AssertsExecutionResults, AssertsCompiledSQL
from sqlalchemy import testing
from sqlalchemy import Table, Column, Integer, String, select
import pytest

from sqlalchemy.testing.suite import * # noqa
from sqlalchemy.testing.suite import * # noqa


class CompoundSelectTest(_CompoundSelectTest):
Expand All @@ -14,3 +18,63 @@ def test_limit_offset_aliased_selectable_in_unions(self):
@pytest.mark.skip()
class QuotedNameArgumentTest(_QuotedNameArgumentTest):
pass


class FetchLimitOffsetTest(_FetchLimitOffsetTest):

def test_simple_offset_no_order(self, connection):
table = self.tables.some_table
self._assert_result(
connection,
select(table).offset(2),
[(3, 3, 4), (4, 4, 5), (5, 4, 6)],
)
self._assert_result(
connection,
select(table).offset(3),
[(4, 4, 5), (5, 4, 6)],
)

@testing.combinations(
([(2, 0), (2, 1), (3, 2)]),
([(2, 1), (2, 0), (3, 2)]),
([(3, 1), (2, 1), (3, 1)]),
argnames="cases",
)
def test_simple_limit_offset_no_order(self, connection, cases):
table = self.tables.some_table
connection = connection.execution_options(compiled_cache={})

assert_data = [(1, 1, 2), (2, 2, 3), (3, 3, 4), (4, 4, 5), (5, 4, 6)]

for limit, offset in cases:
expected = assert_data[offset: offset + limit]
self._assert_result(
connection,
select(table).limit(limit).offset(offset),
expected,
)


class MiscTest(AssertsExecutionResults, AssertsCompiledSQL, fixtures.TablesTest):

__backend__ = True

__only_on__ = "iris"

@classmethod
def define_tables(cls, metadata):
Table(
"some_table",
metadata,
Column("id", Integer, primary_key=True),
Column("x", Integer),
Column("y", Integer),
Column("z", String(50)),
)

# def test_compile(self):
# table = self.tables.some_table

# stmt = select(table.c.id, table.c.x).offset(20).limit(10)

0 comments on commit 73c83e9

Please sign in to comment.