Skip to content

Commit c99b6ea

Browse files
committed
SA20: Fix unexpected keyword argument 'info_cache' on introspection
Both methods `CrateDialect.{has_schema,has_table}` need to accept and forward keyword arguments, in order to comply to the intended interface, starting with SQLAlchemy 2.0. Otherwise, those errors would be raised: - TypeError: CrateDialect.has_schema() got an unexpected keyword argument 'info_cache' - TypeError: CrateDialect.has_table() got an unexpected keyword argument 'info_cache'
1 parent 95332ec commit c99b6ea

File tree

3 files changed

+35
-6
lines changed

3 files changed

+35
-6
lines changed

CHANGES.txt

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Changes for crate
55
Unreleased
66
==========
77

8+
- Fixed SQLAlchemy 2.0 incompatibility with ``CrateDialect.{has_schema,has_table}``
89

910
2023/02/16 0.30.0
1011
=================

src/crate/client/sqlalchemy/dialect.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -227,11 +227,11 @@ def import_dbapi(cls):
227227
def dbapi(cls):
228228
return cls.import_dbapi()
229229

230-
def has_schema(self, connection, schema):
231-
return schema in self.get_schema_names(connection)
230+
def has_schema(self, connection, schema, **kw):
231+
return schema in self.get_schema_names(connection, **kw)
232232

233-
def has_table(self, connection, table_name, schema=None):
234-
return table_name in self.get_table_names(connection, schema=schema)
233+
def has_table(self, connection, table_name, schema=None, **kw):
234+
return table_name in self.get_table_names(connection, schema=schema, **kw)
235235

236236
@reflection.cache
237237
def get_schema_names(self, connection, **kw):

src/crate/client/sqlalchemy/tests/dialect_test.py

+30-2
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,22 @@
2020
# software solely pursuant to the terms of the relevant commercial agreement.
2121

2222
from datetime import datetime
23-
from unittest import TestCase
23+
from unittest import TestCase, skipIf
2424
from unittest.mock import MagicMock, patch
2525

2626
import sqlalchemy as sa
2727

2828
from crate.client.cursor import Cursor
29+
from crate.client.sqlalchemy import SA_VERSION
30+
from crate.client.sqlalchemy.sa_version import SA_1_4, SA_2_0
2931
from crate.client.sqlalchemy.types import Object
3032
from sqlalchemy import inspect
3133
from sqlalchemy.orm import Session
3234
try:
3335
from sqlalchemy.orm import declarative_base
3436
except ImportError:
3537
from sqlalchemy.ext.declarative import declarative_base
36-
from sqlalchemy.testing import eq_, in_
38+
from sqlalchemy.testing import eq_, in_, is_true
3739

3840
FakeCursor = MagicMock(name='FakeCursor', spec=Cursor)
3941

@@ -70,6 +72,13 @@ class Character(self.base):
7072

7173
self.session = Session(bind=self.engine)
7274

75+
def init_mock(self, return_value=None):
76+
self.fake_cursor.rowcount = 1
77+
self.fake_cursor.description = (
78+
('foo', None, None, None, None, None, None),
79+
)
80+
self.fake_cursor.fetchall = MagicMock(return_value=return_value)
81+
7382
def test_primary_keys_2_3_0(self):
7483
insp = inspect(self.session.bind)
7584
self.engine.dialect.server_version_info = (2, 3, 0)
@@ -126,3 +135,22 @@ def test_get_view_names(self):
126135
['v1', 'v2'])
127136
eq_(self.executed_statement, "SELECT table_name FROM information_schema.views "
128137
"ORDER BY table_name ASC, table_schema ASC")
138+
139+
@skipIf(SA_VERSION < SA_1_4, "Inspector.has_table only available on SQLAlchemy>=1.4")
140+
def test_has_table(self):
141+
self.init_mock(return_value=[["foo"], ["bar"]])
142+
insp = inspect(self.session.bind)
143+
is_true(insp.has_table("bar"))
144+
eq_(self.executed_statement,
145+
"SELECT table_name FROM information_schema.tables "
146+
"WHERE table_schema = ? AND table_type = 'BASE TABLE' "
147+
"ORDER BY table_name ASC, table_schema ASC")
148+
149+
@skipIf(SA_VERSION < SA_2_0, "Inspector.has_schema only available on SQLAlchemy>=2.0")
150+
def test_has_schema(self):
151+
self.init_mock(
152+
return_value=[["blob"], ["doc"], ["information_schema"], ["pg_catalog"], ["sys"]])
153+
insp = inspect(self.session.bind)
154+
is_true(insp.has_schema("doc"))
155+
eq_(self.executed_statement,
156+
"select schema_name from information_schema.schemata order by schema_name asc")

0 commit comments

Comments
 (0)