Skip to content

Commit 8d2f78b

Browse files
committed
SA14/Tests: Declare column expressions for _score as literal_column
With the original code, SA14 would croak like:: sqlalchemy.exc.ArgumentError: Textual column expression '_score' should be explicitly declared with text('_score'), or use column('_score') for more specificity However, when using the `sa.text` type, as suggested, older SQLAlchemy versions will croak in this manner:: sqlalchemy.exc.InvalidRequestError: SQL expression, column, or mapped entity expected - got '<sqlalchemy.sql.elements.TextClause object at 0x10c0f7460>' The `sa.column` type also will not work, because it would get rendered with quotes as `"_score"`. > `literal_column()` is similar to `column()`, except that it is more > often used as a “standalone” column expression that renders exactly > as stated. > > -- https://docs.sqlalchemy.org/en/14/core/sqlelement.html#sqlalchemy.sql.expression.literal_column :: - SELECT characters.name AS characters_name, _score FROM characters WHERE match(characters.name, ?) + SELECT characters.name AS characters_name, "_score" FROM characters WHERE match(characters.name, ?) Settling with the `sa.literal_column` type resolved any woes.
1 parent 0257794 commit 8d2f78b

File tree

3 files changed

+38
-4
lines changed

3 files changed

+38
-4
lines changed

CHANGES.txt

+34
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,40 @@ Unreleased
1818

1919
- Add support for SQLAlchemy 1.4
2020

21+
22+
Breaking changes
23+
----------------
24+
25+
Textual column expressions
26+
''''''''''''''''''''''''''
27+
28+
On the update to SQLAlchemy 1.4, some test cases had to be adjusted in order
29+
to compensate for apparent additional strictness of SQLAlchemy on some details.
30+
31+
Where it was ok to use a textual column expression in plain text beforehand,
32+
a `SQLAlchemy literal_column`_ type should be used now. Otherwise, for example
33+
when accessing `CrateDB system columns`_ like ``_score``, the engine might
34+
complain like::
35+
36+
sqlalchemy.exc.ArgumentError: Textual column expression '_score' should be
37+
explicitly declared with text('_score'), or use column('_score') for more
38+
specificity
39+
40+
The changes to be made look like this::
41+
42+
old: session.query(Character.name, '_score')
43+
new: session.query(Character.name, sa.literal_column('_score'))
44+
45+
::
46+
47+
old: .order_by(sa.desc(sa.text('_score')))
48+
new: .order_by(sa.desc(sa.literal_column('_score')))
49+
50+
51+
.. _SQLAlchemy literal_column: https://docs.sqlalchemy.org/en/14/core/sqlelement.html#sqlalchemy.sql.expression.literal_column
52+
.. _CrateDB system columns: https://crate.io/docs/crate/reference/en/4.8/general/ddl/system-columns.html
53+
54+
2155
2020/09/28 0.26.0
2256
=================
2357

src/crate/client/doctests/sqlalchemy.txt

+2-3
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ the other rows. The higher the score value, the more relevant the row.
289289
In most cases ``_score`` is not part of the SQLAlchemy Table definition,
290290
so it must be passed as a string::
291291

292-
>>> session.query(Character.name, '_score') \
292+
>>> session.query(Character.name, sa.literal_column('_score')) \
293293
... .filter(match(Character.quote_ft, 'space')) \
294294
... .all()
295295
[('Tricia McMillan', ...)]
@@ -298,11 +298,10 @@ To search on multiple columns you have to pass a dictionary with columns
298298
and ``boost`` attached. ``boost`` is a factor that increases the
299299
relevance of a column in respect to the other columns::
300300

301-
>>> from sqlalchemy.sql import text
302301
>>> session.query(Character.name) \
303302
... .filter(match({Character.name_ft: 1.5, Character.quote_ft: 0.1},
304303
... 'Arthur')) \
305-
... .order_by(sa.desc(text('_score'))) \
304+
... .order_by(sa.desc(sa.literal_column('_score'))) \
306305
... .all()
307306
[('Arthur Dent',), ('Tricia McMillan',)]
308307

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ def test_match_type_options(self):
109109
)
110110

111111
def test_score(self):
112-
query = self.session.query(self.Character.name, '_score') \
112+
query = self.session.query(self.Character.name,
113+
sa.literal_column('_score')) \
113114
.filter(match(self.Character.name, 'Trillian'))
114115
self.assertSQL(
115116
"SELECT characters.name AS characters_name, _score " +

0 commit comments

Comments
 (0)