Skip to content

Commit

Permalink
Add minimal SQLAlchemy 1.4 compatibility for CrateCompiler
Browse files Browse the repository at this point in the history
> A major initiative in the 1.4 series is to approach the model of both
Core SQL statements as well as the ORM Query to allow for an efficient,
cacheable model of statement creation and compilation, where the
compilation step would be cached, based on a cache key generated by the
created statement object, which itself is newly created for each use.

While there is probably more to it, this patch tries to at least make
the CrateCompiler work with the new subsystem infrastructure.
  • Loading branch information
amotl committed Nov 16, 2020
1 parent 8ba3b99 commit 0b1d8cb
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 15 deletions.
76 changes: 61 additions & 15 deletions src/crate/client/sqlalchemy/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from sqlalchemy.sql import crud
from sqlalchemy.sql import compiler
from .types import MutableDict
from .sa_version import SA_1_1, SA_VERSION
from .sa_version import SA_1_1, SA_1_4, SA_VERSION


def rewrite_update(clauseelement, multiparams, params):
Expand Down Expand Up @@ -198,7 +198,20 @@ def visit_insert(self, insert_stmt, asfrom=False, **kw):
"selectable": insert_stmt})

self.isinsert = True
crud_params = crud._get_crud_params(self, insert_stmt, **kw)

if SA_VERSION >= SA_1_4:
# Minimal patch to be compatible with SQLAlchemy 1.4.
# For a more thorough implementation, please follow
# https://github.com/crate/crate-python/pull/391.
compile_state = insert_stmt._compile_state_factory(
insert_stmt, self, **kw
)
insert_stmt = compile_state.statement
crud_params = crud._get_crud_params(self, insert_stmt, compile_state, **kw)
_has_multi_parameters = compile_state._has_multi_parameters
else:
crud_params = crud._get_crud_params(self, insert_stmt, **kw)
_has_multi_parameters = insert_stmt._has_multi_parameters

if not crud_params and \
not self.dialect.supports_default_values and \
Expand All @@ -207,7 +220,7 @@ def visit_insert(self, insert_stmt, asfrom=False, **kw):
"The '%s' dialect with current database version settings does "
"not support empty inserts." % self.dialect.name)

if insert_stmt._has_multi_parameters:
if _has_multi_parameters:
if not self.dialect.supports_multivalues_insert:
raise NotImplementedError(
"The '%s' dialect with current database "
Expand Down Expand Up @@ -262,7 +275,7 @@ def visit_insert(self, insert_stmt, asfrom=False, **kw):
text += " (%s)" % self.process(self._insert_from_select, **kw)
elif not crud_params and supports_default_values:
text += " DEFAULT VALUES"
elif insert_stmt._has_multi_parameters:
elif _has_multi_parameters:
text += " VALUES %s" % (
", ".join(
"(%s)" % (
Expand Down Expand Up @@ -294,7 +307,16 @@ def visit_update(self, update_stmt, **kw):

self.isupdate = True

extra_froms = update_stmt._extra_froms
if SA_VERSION >= SA_1_4:
# Minimal patch to be compatible with SQLAlchemy 1.4.
# For a more thorough implementation, please follow
# https://github.com/crate/crate-python/pull/391.
compile_state = update_stmt._compile_state_factory(
update_stmt, compiler, **kw
)
extra_froms = compile_state._extra_froms
else:
extra_froms = update_stmt._extra_froms

text = 'UPDATE '

Expand Down Expand Up @@ -351,10 +373,21 @@ def visit_update(self, update_stmt, **kw):
if extra_from_text:
text += " " + extra_from_text

if update_stmt._whereclause is not None:
t = self.process(update_stmt._whereclause)
if t:
text += " WHERE " + t
if SA_VERSION >= SA_1_4:
# Minimal patch to be compatible with SQLAlchemy 1.4.
# For a more thorough implementation, please follow
# https://github.com/crate/crate-python/pull/391.
if update_stmt._where_criteria:
t = self._generate_delimited_and_list(
update_stmt._where_criteria, **kw
)
if t:
text += " WHERE " + t
else:
if update_stmt._whereclause is not None:
t = self.process(update_stmt._whereclause)
if t:
text += " WHERE " + t

limit_clause = self.update_limit_clause(update_stmt)
if limit_clause:
Expand Down Expand Up @@ -384,20 +417,33 @@ def _get_crud_params(compiler, stmt, **kw):
required=True))
for c in stmt.table.columns]

if stmt._has_multi_parameters:
stmt_parameters = stmt.parameters[0]
else:
stmt_parameters = stmt.parameters

# getters - these are normally just column.key,
# but in the case of mysql multi-table update, the rules for
# .key must conditionally take tablename into account
if SA_VERSION >= SA_1_1:
if SA_VERSION >= SA_1_4:
# Minimal patch to be compatible with SQLAlchemy 1.4.
# For a more thorough implementation, please follow
# https://github.com/crate/crate-python/pull/391.
compile_state = stmt._compile_state_factory(
stmt, compiler, **kw
)
stmt = compile_state.statement
_column_as_key, _getattr_col_key, _col_bind_name = \
crud._key_getters_for_crud_column(compiler, stmt, compile_state)
_has_multi_parameters = compile_state._has_multi_parameters
elif SA_VERSION >= SA_1_1:
_column_as_key, _getattr_col_key, _col_bind_name = \
crud._key_getters_for_crud_column(compiler, stmt)
_has_multi_parameters = stmt._has_multi_parameters
else:
_column_as_key, _getattr_col_key, _col_bind_name = \
crud._key_getters_for_crud_column(compiler)
_has_multi_parameters = stmt._has_multi_parameters

if _has_multi_parameters:
stmt_parameters = stmt.parameters[0]
else:
stmt_parameters = stmt.parameters

# if we have statement parameters - set defaults in the
# compiled params
Expand Down
1 change: 1 addition & 0 deletions src/crate/client/sqlalchemy/sa_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@
SA_VERSION = V(sa.__version__)

SA_1_1 = V('1.1a0')
SA_1_4 = V('1.4.0b1')

0 comments on commit 0b1d8cb

Please sign in to comment.