summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2020-08-17 17:24:27 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2020-09-16 12:31:05 -0400
commit7e864fc7b1b950760cbf02e6dcd5aa5aac267400 (patch)
tree2382b016c3eb82ae463719cc948f45ccd2a226a2 /lib/sqlalchemy
parent8ebc8184392e20727748cd1405245e527f17e111 (diff)
downloadsqlalchemy-7e864fc7b1b950760cbf02e6dcd5aa5aac267400.tar.gz
Create a framework to allow all SQLALCHEMY_WARN_20 to pass
As the test suite has widespread use of many patterns that are deprecated, enable SQLALCHEMY_WARN_20 globally for the test suite but then break the warnings filter out into a whole list of all the individual warnings we are looking for. this way individual changesets can target a specific class of warning, as many of these warnings will indivdidually affect dozens of files and potentially hundreds of lines of code. Many warnings are also resolved here as this patch started out that way. From this point forward there should be changesets that target a subset of the warnings at a time. For expediency, updates some migration 2.0 docs for ORM as well. Change-Id: I98b8defdf7c37b818b3824d02f7668e3f5f31c94
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r--lib/sqlalchemy/engine/base.py1
-rw-r--r--lib/sqlalchemy/engine/util.py1
-rw-r--r--lib/sqlalchemy/ext/horizontal_shard.py4
-rw-r--r--lib/sqlalchemy/orm/decl_api.py4
-rw-r--r--lib/sqlalchemy/orm/mapper.py2
-rw-r--r--lib/sqlalchemy/orm/query.py13
-rw-r--r--lib/sqlalchemy/orm/util.py17
-rw-r--r--lib/sqlalchemy/sql/dml.py5
-rw-r--r--lib/sqlalchemy/sql/selectable.py2
-rw-r--r--lib/sqlalchemy/testing/fixtures.py6
-rw-r--r--lib/sqlalchemy/testing/profiling.py25
-rw-r--r--lib/sqlalchemy/testing/suite/test_insert.py8
-rw-r--r--lib/sqlalchemy/testing/warnings.py74
13 files changed, 135 insertions, 27 deletions
diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py
index 63f2af7ef..6aa2e7b14 100644
--- a/lib/sqlalchemy/engine/base.py
+++ b/lib/sqlalchemy/engine/base.py
@@ -1350,6 +1350,7 @@ class Connection(Connectable):
)
dialect = self.dialect
+
ret = self._execute_context(
dialect,
dialect.execution_ctx_cls._init_compiled,
diff --git a/lib/sqlalchemy/engine/util.py b/lib/sqlalchemy/engine/util.py
index c1f6bad77..26dd5ddd0 100644
--- a/lib/sqlalchemy/engine/util.py
+++ b/lib/sqlalchemy/engine/util.py
@@ -73,7 +73,6 @@ def py_fallback():
# textual statement with positional parameters to
# execute().
# execute(stmt, ("value", "value"))
-
return [zero]
elif hasattr(zero, "keys"):
# execute(stmt, {"key":"value"})
diff --git a/lib/sqlalchemy/ext/horizontal_shard.py b/lib/sqlalchemy/ext/horizontal_shard.py
index fe9bbaf02..220cdbfc8 100644
--- a/lib/sqlalchemy/ext/horizontal_shard.py
+++ b/lib/sqlalchemy/ext/horizontal_shard.py
@@ -186,8 +186,8 @@ class ShardedSession(Session):
if shard_id is None:
shard_id = self._choose_shard_and_assign(mapper, instance)
- if self.transaction is not None:
- return self.transaction.connection(mapper, shard_id=shard_id)
+ if self.in_transaction():
+ return self.get_transaction().connection(mapper, shard_id=shard_id)
else:
return self.get_bind(
mapper, shard_id=shard_id, instance=instance
diff --git a/lib/sqlalchemy/orm/decl_api.py b/lib/sqlalchemy/orm/decl_api.py
index 68de18c2e..41cc88112 100644
--- a/lib/sqlalchemy/orm/decl_api.py
+++ b/lib/sqlalchemy/orm/decl_api.py
@@ -366,7 +366,7 @@ def declarative_base(
if bind is not None:
# util.deprecated_params does not work
util.warn_deprecated_20(
- 'The "bind" argument to declarative_base is'
+ "The ``bind`` argument to declarative_base is "
"deprecated and will be removed in SQLAlchemy 2.0.",
)
@@ -701,7 +701,7 @@ class registry(object):
@util.deprecated_params(
bind=(
"2.0",
- 'The "bind" argument to declarative_base is'
+ "The ``bind`` argument to as_declarative is "
"deprecated and will be removed in SQLAlchemy 2.0.",
)
)
diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py
index db2b94a4e..821c8a3c8 100644
--- a/lib/sqlalchemy/orm/mapper.py
+++ b/lib/sqlalchemy/orm/mapper.py
@@ -3014,7 +3014,7 @@ class Mapper(
cols = []
for key in col_attribute_names:
cols.extend(props[key].columns)
- return sql.select(cols, cond, use_labels=True)
+ return sql.select(*cols).where(cond).apply_labels()
def _iterate_to_target_viawpoly(self, mapper):
if self.isa(mapper):
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py
index 91a638e4b..9587fcd6c 100644
--- a/lib/sqlalchemy/orm/query.py
+++ b/lib/sqlalchemy/orm/query.py
@@ -2915,7 +2915,7 @@ class Query(
self.enable_eagerloads(False)
.add_columns(sql.literal_column("1"))
.with_labels()
- .statement.with_only_columns([1])
+ .statement.with_only_columns(1)
)
ezero = self._entity_from_pre_ent_zero()
@@ -3098,7 +3098,16 @@ class Query(
bulk_ud.query = new_query
self = bulk_ud.query
- upd = sql.update(*self._raw_columns, **update_args).values(values)
+ upd = sql.update(*self._raw_columns)
+
+ ppo = update_args.pop("preserve_parameter_order", False)
+ if ppo:
+ upd = upd.ordered_values(*values)
+ else:
+ upd = upd.values(values)
+ if update_args:
+ upd = upd.with_dialect_options(**update_args)
+
upd._where_criteria = self._where_criteria
result = self.session.execute(
upd,
diff --git a/lib/sqlalchemy/orm/util.py b/lib/sqlalchemy/orm/util.py
index f7673e0b7..2bfba16b5 100644
--- a/lib/sqlalchemy/orm/util.py
+++ b/lib/sqlalchemy/orm/util.py
@@ -245,13 +245,18 @@ def polymorphic_union(
result = []
for type_, table in table_map.items():
if typecolname is not None:
- cols = [col(name, table) for name in colnames]
- cols.append(
- sql.literal_column(sql_util._quote_ddl_expr(type_)).label(
- typecolname
- ),
+ result.append(
+ sql.select(
+ *(
+ [col(name, table) for name in colnames]
+ + [
+ sql.literal_column(
+ sql_util._quote_ddl_expr(type_)
+ ).label(typecolname)
+ ]
+ )
+ ).select_from(table)
)
- result.append(sql.select(*cols).select_from(table))
else:
result.append(
sql.select(
diff --git a/lib/sqlalchemy/sql/dml.py b/lib/sqlalchemy/sql/dml.py
index cd4bc17af..fd2efc6f9 100644
--- a/lib/sqlalchemy/sql/dml.py
+++ b/lib/sqlalchemy/sql/dml.py
@@ -215,7 +215,7 @@ class UpdateBase(
"The :paramref:`%(func)s.whereclause` parameter "
"will be removed "
"in SQLAlchemy 2.0. Please refer to the "
- ":meth:`.%(classname)s.where` method."
+ ":meth:`%(classname)s.where` method."
),
values=(
"The :paramref:`%(func)s.values` parameter will be removed "
@@ -308,8 +308,9 @@ class UpdateBase(
def _validate_dialect_kwargs_deprecated(self, dialect_kw):
util.warn_deprecated_20(
"Passing dialect keyword arguments directly to the "
- "constructor is deprecated and will be removed in SQLAlchemy "
+ "%s constructor is deprecated and will be removed in SQLAlchemy "
"2.0. Please use the ``with_dialect_options()`` method."
+ % (self.__class__.__name__)
)
self._validate_dialect_kwargs(dialect_kw)
diff --git a/lib/sqlalchemy/sql/selectable.py b/lib/sqlalchemy/sql/selectable.py
index 0c808e7a7..6e0ac1fac 100644
--- a/lib/sqlalchemy/sql/selectable.py
+++ b/lib/sqlalchemy/sql/selectable.py
@@ -4612,7 +4612,7 @@ class Select(
"""
return self.with_only_columns(
- util.preloaded.sql_util.reduce_columns(
+ *util.preloaded.sql_util.reduce_columns(
self._exported_columns_iterator(),
only_synonyms=only_synonyms,
*(self._where_criteria + self._from_obj)
diff --git a/lib/sqlalchemy/testing/fixtures.py b/lib/sqlalchemy/testing/fixtures.py
index 2d3b27917..54b1cbb46 100644
--- a/lib/sqlalchemy/testing/fixtures.py
+++ b/lib/sqlalchemy/testing/fixtures.py
@@ -330,6 +330,12 @@ class _ORMTest(object):
sa.orm.clear_mappers()
+def create_session(**kw):
+ kw.setdefault("autoflush", False)
+ kw.setdefault("expire_on_commit", False)
+ return sa.orm.Session(config.db, **kw)
+
+
class ORMTest(_ORMTest, TestBase):
pass
diff --git a/lib/sqlalchemy/testing/profiling.py b/lib/sqlalchemy/testing/profiling.py
index f52827ca5..48e44428b 100644
--- a/lib/sqlalchemy/testing/profiling.py
+++ b/lib/sqlalchemy/testing/profiling.py
@@ -241,17 +241,26 @@ def function_call_count(variance=0.05, times=1, warmup=0):
# likely due to the introduction of __signature__.
from sqlalchemy.util import decorator
+ from sqlalchemy.util import deprecations
+ from sqlalchemy.engine import row
+ from sqlalchemy.testing import mock
@decorator
def wrap(fn, *args, **kw):
- for warm in range(warmup):
- fn(*args, **kw)
-
- timerange = range(times)
- with count_functions(variance=variance):
- for time in timerange:
- rv = fn(*args, **kw)
- return rv
+
+ with mock.patch.object(
+ deprecations, "SQLALCHEMY_WARN_20", False
+ ), mock.patch.object(
+ row.LegacyRow, "_default_key_style", row.KEY_OBJECTS_NO_WARN
+ ):
+ for warm in range(warmup):
+ fn(*args, **kw)
+
+ timerange = range(times)
+ with count_functions(variance=variance):
+ for time in timerange:
+ rv = fn(*args, **kw)
+ return rv
return wrap
diff --git a/lib/sqlalchemy/testing/suite/test_insert.py b/lib/sqlalchemy/testing/suite/test_insert.py
index 74347cc77..7a7eac02f 100644
--- a/lib/sqlalchemy/testing/suite/test_insert.py
+++ b/lib/sqlalchemy/testing/suite/test_insert.py
@@ -225,7 +225,9 @@ class InsertBehaviorTest(fixtures.TablesTest):
)
connection.execute(
- table.insert(inline=True).from_select(
+ table.insert()
+ .inline()
+ .from_select(
("id", "data"),
select(table.c.id + 5, table.c.data).where(
table.c.data.in_(["data2", "data3"])
@@ -253,7 +255,9 @@ class InsertBehaviorTest(fixtures.TablesTest):
)
connection.execute(
- table.insert(inline=True).from_select(
+ table.insert()
+ .inline()
+ .from_select(
("id", "data"),
select(table.c.id + 5, table.c.data).where(
table.c.data.in_(["data2", "data3"])
diff --git a/lib/sqlalchemy/testing/warnings.py b/lib/sqlalchemy/testing/warnings.py
index 298b20c11..de5db6467 100644
--- a/lib/sqlalchemy/testing/warnings.py
+++ b/lib/sqlalchemy/testing/warnings.py
@@ -43,6 +43,80 @@ def setup_filters():
message=r"^The (Sybase|firebird) dialect is deprecated and will be",
)
+ # 2.0 deprecation warnings, which we will want to have all of these
+ # be "error" however for I98b8defdf7c37b818b3824d02f7668e3f5f31c94
+ # we are moving one at a time
+ for msg in [
+ #
+ # Core execution
+ #
+ r"The (?:Executable|Engine)\.(?:execute|scalar)\(\) function",
+ r"The current statement is being autocommitted using implicit "
+ "autocommit,",
+ r"The connection.execute\(\) method in SQLAlchemy 2.0 will accept "
+ "parameters as a single dictionary or a single sequence of "
+ "dictionaries only.",
+ r"The Connection.connect\(\) function/method is considered legacy",
+ r".*DefaultGenerator.execute\(\)",
+ #
+ # result sets
+ #
+ r"The Row.keys\(\) function/method",
+ r"Using non-integer/slice indices on Row ",
+ #
+ # Core SQL constructs
+ #
+ r"The FromClause\.select\(\).whereclause parameter is deprecated",
+ r"Set functions such as union\(\), union_all\(\), extract\(\),",
+ r"The legacy calling style of select\(\) is deprecated and will be "
+ "removed",
+ r"The FromClause.select\(\) method will no longer accept keyword "
+ "arguments in version 2.0",
+ r"The Join.select\(\) method will no longer accept keyword arguments "
+ "in version 2.0.",
+ r"The \"whens\" argument to case\(\) is now passed",
+ r"The Join.select\(\).whereclause parameter is deprecated",
+ #
+ # DML
+ #
+ r"The (?:update|delete).whereclause parameter will be removed in "
+ "SQLAlchemy 2.0.",
+ r"The (?:insert|update).values parameter will be removed in "
+ "SQLAlchemy 2.0.",
+ r"The update.preserve_parameter_order parameter will be removed in "
+ "SQLAlchemy 2.0.",
+ r"Passing dialect keyword arguments directly to the "
+ "(?:Insert|Update|Delete) constructor",
+ #
+ # ORM configuration
+ #
+ r"Calling the mapper\(\) function directly outside of a "
+ "declarative registry",
+ r"The ``declarative_base\(\)`` function is now available ",
+ r"The ``has_inherited_table\(\)`` function is now available",
+ r"The ``bind`` argument to declarative_base is deprecated and will "
+ "be removed in SQLAlchemy 2.0.",
+ #
+ # ORM Query
+ #
+ r"The Query\.get\(\) function",
+ r"The Query\.from_self\(\) function",
+ #
+ # ORM Session
+ #
+ r"The Session.autocommit parameter is deprecated ",
+ r".*object is being merged into a Session along the backref "
+ "cascade path",
+ r"Passing bind arguments to Session.execute\(\) as keyword arguments",
+ r"The Session.transaction function/method",
+ r"The merge_result\(\) method is superseded by the "
+ r"merge_frozen_result\(\)",
+ r"The Session.begin.subtransactions flag is deprecated",
+ ]:
+ warnings.filterwarnings(
+ "ignore", message=msg, category=sa_exc.RemovedIn20Warning,
+ )
+
try:
import pytest
except ImportError: