summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r--lib/sqlalchemy/orm/query.py7
-rw-r--r--lib/sqlalchemy/orm/relationships.py1
-rw-r--r--lib/sqlalchemy/sql/compiler.py22
-rw-r--r--lib/sqlalchemy/sql/selectable.py7
-rw-r--r--lib/sqlalchemy/sql/sqltypes.py7
-rw-r--r--lib/sqlalchemy/sql/util.py6
-rw-r--r--lib/sqlalchemy/testing/requirements.py4
-rw-r--r--lib/sqlalchemy/util/__init__.py1
-rw-r--r--lib/sqlalchemy/util/compat.py1
9 files changed, 40 insertions, 16 deletions
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py
index 9ac6d07da..2d97754f4 100644
--- a/lib/sqlalchemy/orm/query.py
+++ b/lib/sqlalchemy/orm/query.py
@@ -1963,9 +1963,10 @@ class Query(
q = session.query(Entity).order_by(Entity.id, Entity.name)
- All existing ORDER BY criteria may be cancelled by passing
- ``None`` by itself. New ORDER BY criteria may then be added by
- invoking :meth:`_orm.Query.order_by` again, e.g.::
+ Calling this method multiple times is equivalent to calling it once
+ with all the clauses concatenated. All existing ORDER BY criteria may
+ be cancelled by passing ``None`` by itself. New ORDER BY criteria may
+ then be added by invoking :meth:`_orm.Query.order_by` again, e.g.::
# will erase all ORDER BY and ORDER BY new_col alone
q = q.order_by(None).order_by(new_col)
diff --git a/lib/sqlalchemy/orm/relationships.py b/lib/sqlalchemy/orm/relationships.py
index e0922a538..986093e02 100644
--- a/lib/sqlalchemy/orm/relationships.py
+++ b/lib/sqlalchemy/orm/relationships.py
@@ -164,6 +164,7 @@ _ORMOrderByArgument = Union[
Literal[False],
str,
_ColumnExpressionArgument[Any],
+ Callable[[], Iterable[ColumnElement[Any]]],
Iterable[Union[str, _ColumnExpressionArgument[Any]]],
]
_ORMBackrefArgument = Union[str, Tuple[str, Dict[str, Any]]]
diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py
index 97397e9cf..9a00afc91 100644
--- a/lib/sqlalchemy/sql/compiler.py
+++ b/lib/sqlalchemy/sql/compiler.py
@@ -63,6 +63,7 @@ from . import roles
from . import schema
from . import selectable
from . import sqltypes
+from . import util as sql_util
from ._typing import is_column_element
from ._typing import is_dml
from .base import _from_objects
@@ -1530,7 +1531,8 @@ class SQLCompiler(Compiled):
replacement_expressions[
escaped_name
] = self.render_literal_bindparam(
- parameter, render_literal_value=value
+ parameter,
+ render_literal_value=value,
)
continue
@@ -3154,10 +3156,22 @@ class SQLCompiler(Compiled):
processor = type_._cached_literal_processor(self.dialect)
if processor:
- return processor(value)
+ try:
+ return processor(value)
+ except Exception as e:
+ raise exc.CompileError(
+ f"Could not render literal value "
+ f'"{sql_util._repr_single_value(value)}" '
+ f"with datatype "
+ f"{type_}; see parent stack trace for "
+ "more detail."
+ ) from e
+
else:
- raise NotImplementedError(
- "Don't know how to literal-quote value %r" % value
+ raise exc.CompileError(
+ f"No literal value renderer is available for literal value "
+ f'"{sql_util._repr_single_value(value)}" '
+ f"with datatype {type_}"
)
def _truncate_bindparam(self, bindparam):
diff --git a/lib/sqlalchemy/sql/selectable.py b/lib/sqlalchemy/sql/selectable.py
index 01b12efac..8c64dea9d 100644
--- a/lib/sqlalchemy/sql/selectable.py
+++ b/lib/sqlalchemy/sql/selectable.py
@@ -4111,9 +4111,10 @@ class GenerativeSelect(SelectBase, Generative):
stmt = select(table).order_by(table.c.id, table.c.name)
- All existing ORDER BY criteria may be cancelled by passing
- ``None`` by itself. New ORDER BY criteria may then be added by
- invoking :meth:`_sql.Select.order_by` again, e.g.::
+ Calling this method multiple times is equivalent to calling it once
+ with all the clauses concatenated. All existing ORDER BY criteria may
+ be cancelled by passing ``None`` by itself. New ORDER BY criteria may
+ then be added by invoking :meth:`_orm.Query.order_by` again, e.g.::
# will erase all ORDER BY and ORDER BY new_col alone
stmt = stmt.order_by(None).order_by(new_col)
diff --git a/lib/sqlalchemy/sql/sqltypes.py b/lib/sqlalchemy/sql/sqltypes.py
index 414ff03c3..b98a16b6f 100644
--- a/lib/sqlalchemy/sql/sqltypes.py
+++ b/lib/sqlalchemy/sql/sqltypes.py
@@ -3381,12 +3381,7 @@ class NullType(TypeEngine[None]):
_isnull = True
def literal_processor(self, dialect):
- def process(value):
- raise exc.CompileError(
- "Don't know how to render literal SQL value: %r" % (value,)
- )
-
- return process
+ return None
class Comparator(TypeEngine.Comparator[_T]):
__slots__ = ()
diff --git a/lib/sqlalchemy/sql/util.py b/lib/sqlalchemy/sql/util.py
index 623a3f896..ec8ea757f 100644
--- a/lib/sqlalchemy/sql/util.py
+++ b/lib/sqlalchemy/sql/util.py
@@ -581,6 +581,12 @@ class _repr_base:
return rep
+def _repr_single_value(value):
+ rp = _repr_base()
+ rp.max_chars = 300
+ return rp.trunc(value)
+
+
class _repr_row(_repr_base):
"""Provide a string view of a row."""
diff --git a/lib/sqlalchemy/testing/requirements.py b/lib/sqlalchemy/testing/requirements.py
index 38d962fef..3c63e9362 100644
--- a/lib/sqlalchemy/testing/requirements.py
+++ b/lib/sqlalchemy/testing/requirements.py
@@ -1439,6 +1439,10 @@ class SuiteRequirements(Requirements):
)
@property
+ def is64bit(self):
+ return exclusions.only_if(lambda: util.is64bit, "64bit required")
+
+ @property
def patch_library(self):
def check_lib():
try:
diff --git a/lib/sqlalchemy/util/__init__.py b/lib/sqlalchemy/util/__init__.py
index bb4642a4f..e82cfd769 100644
--- a/lib/sqlalchemy/util/__init__.py
+++ b/lib/sqlalchemy/util/__init__.py
@@ -58,6 +58,7 @@ from .compat import decode_backslashreplace as decode_backslashreplace
from .compat import dottedgetter as dottedgetter
from .compat import has_refcount_gc as has_refcount_gc
from .compat import inspect_getfullargspec as inspect_getfullargspec
+from .compat import is64bit as is64bit
from .compat import local_dataclass_fields as local_dataclass_fields
from .compat import osx as osx
from .compat import py310 as py310
diff --git a/lib/sqlalchemy/util/compat.py b/lib/sqlalchemy/util/compat.py
index 2899b4258..24f9bcf10 100644
--- a/lib/sqlalchemy/util/compat.py
+++ b/lib/sqlalchemy/util/compat.py
@@ -41,6 +41,7 @@ cpython = platform.python_implementation() == "CPython"
win32 = sys.platform.startswith("win")
osx = sys.platform.startswith("darwin")
arm = "aarch" in platform.machine().lower()
+is64bit = platform.architecture()[0] == "64bit"
has_refcount_gc = bool(cpython)