Skip to content

Commit a946dde

Browse files
Avoid using deprecated 'body' parameter
Co-authored-by: Quentin Pradet <[email protected]>
1 parent 157d014 commit a946dde

File tree

8 files changed

+91
-27
lines changed

8 files changed

+91
-27
lines changed

elasticsearch_dsl/connections.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,16 @@
1515
# specific language governing permissions and limitations
1616
# under the License.
1717

18-
from elasticsearch import Elasticsearch
18+
from elasticsearch import Elasticsearch, __version__
1919
from six import string_types
2020

2121
from .serializer import serializer
2222

23+
# The 'body' parameter was deprecated in favor of named
24+
# body parameters in version 7.15.0 of the client. The relevant APIs
25+
# affected include 'search', 'index', 'update', and 'indices.create'
26+
CLIENT_HAS_NAMED_BODY_PARAMS = __version__ >= (7, 15, 0)
27+
2328

2429
class Connections(object):
2530
"""

elasticsearch_dsl/document.py

+23-15
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from elasticsearch.exceptions import NotFoundError, RequestError
2626
from six import add_metaclass, iteritems
2727

28-
from .connections import get_connection
28+
from .connections import CLIENT_HAS_NAMED_BODY_PARAMS, get_connection
2929
from .exceptions import IllegalOperation, ValidationException
3030
from .field import Field
3131
from .index import Index
@@ -416,22 +416,29 @@ def update(
416416
body["doc"] = {k: values.get(k) for k in fields.keys()}
417417

418418
# extract routing etc from meta
419-
doc_meta = {k: self.meta[k] for k in DOC_META_FIELDS if k in self.meta}
419+
params = {k: self.meta[k] for k in DOC_META_FIELDS if k in self.meta}
420420

421421
if retry_on_conflict is not None:
422-
doc_meta["retry_on_conflict"] = retry_on_conflict
422+
params["retry_on_conflict"] = retry_on_conflict
423423

424424
# Optimistic concurrency control
425425
if (
426426
retry_on_conflict in (None, 0)
427427
and "seq_no" in self.meta
428428
and "primary_term" in self.meta
429429
):
430-
doc_meta["if_seq_no"] = self.meta["seq_no"]
431-
doc_meta["if_primary_term"] = self.meta["primary_term"]
430+
params["if_seq_no"] = self.meta["seq_no"]
431+
params["if_primary_term"] = self.meta["primary_term"]
432+
433+
params["refresh"] = refresh
434+
435+
if CLIENT_HAS_NAMED_BODY_PARAMS:
436+
params.update(body)
437+
else:
438+
params["body"] = body
432439

433440
meta = self._get_connection(using).update(
434-
index=self._get_index(index), body=body, refresh=refresh, **doc_meta
441+
index=self._get_index(index), **params
435442
)
436443
# update meta information from ES
437444
for k in META_FIELDS:
@@ -474,19 +481,20 @@ def save(
474481

475482
es = self._get_connection(using)
476483
# extract routing etc from meta
477-
doc_meta = {k: self.meta[k] for k in DOC_META_FIELDS if k in self.meta}
484+
params = {k: self.meta[k] for k in DOC_META_FIELDS if k in self.meta}
478485

479486
# Optimistic concurrency control
480487
if "seq_no" in self.meta and "primary_term" in self.meta:
481-
doc_meta["if_seq_no"] = self.meta["seq_no"]
482-
doc_meta["if_primary_term"] = self.meta["primary_term"]
488+
params["if_seq_no"] = self.meta["seq_no"]
489+
params["if_primary_term"] = self.meta["primary_term"]
483490

484-
doc_meta.update(kwargs)
485-
meta = es.index(
486-
index=self._get_index(index),
487-
body=self.to_dict(skip_empty=skip_empty),
488-
**doc_meta
489-
)
491+
if CLIENT_HAS_NAMED_BODY_PARAMS:
492+
params["document"] = self.to_dict(skip_empty=skip_empty)
493+
else:
494+
params["body"] = self.to_dict(skip_empty=skip_empty)
495+
496+
params.update(kwargs)
497+
meta = es.index(index=self._get_index(index), **params)
490498
# update meta information from ES
491499
for k in META_FIELDS:
492500
if "_" + k in meta:

elasticsearch_dsl/index.py

+10-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
# under the License.
1717

1818
from . import analysis
19-
from .connections import get_connection
19+
from .connections import CLIENT_HAS_NAMED_BODY_PARAMS, get_connection
2020
from .exceptions import IllegalOperation
2121
from .mapping import Mapping
2222
from .search import Search
@@ -276,9 +276,15 @@ def create(self, using=None, **kwargs):
276276
Any additional keyword arguments will be passed to
277277
``Elasticsearch.indices.create`` unchanged.
278278
"""
279-
return self._get_connection(using).indices.create(
280-
index=self._name, body=self.to_dict(), **kwargs
281-
)
279+
es = self._get_connection(using)
280+
281+
if CLIENT_HAS_NAMED_BODY_PARAMS:
282+
params = self.to_dict()
283+
else:
284+
params = {"body": self.to_dict()}
285+
params.update(kwargs)
286+
287+
return es.indices.create(index=self._name, **params)
282288

283289
def is_closed(self, using=None):
284290
state = self._get_connection(using).cluster.state(

elasticsearch_dsl/search.py

+10-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
from six import iteritems, string_types
2828

2929
from .aggs import A, AggBase
30-
from .connections import get_connection
30+
from .connections import CLIENT_HAS_NAMED_BODY_PARAMS, get_connection
3131
from .exceptions import IllegalOperation
3232
from .query import Bool, Q
3333
from .response import Hit, Response
@@ -711,8 +711,16 @@ def execute(self, ignore_cache=False):
711711
if ignore_cache or not hasattr(self, "_response"):
712712
es = get_connection(self._using)
713713

714+
if CLIENT_HAS_NAMED_BODY_PARAMS:
715+
params = self.to_dict()
716+
if "from" in params:
717+
params["from_"] = params.pop("from")
718+
else:
719+
params = {"body": self.to_dict()}
720+
params.update(self._params)
721+
714722
self._response = self._response_class(
715-
self, es.search(index=self._index, body=self.to_dict(), **self._params)
723+
self, es.search(index=self._index, **params)
716724
)
717725
return self._response
718726

tests/test_integration/test_document.py

+12-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
# specific language governing permissions and limitations
1616
# under the License.
1717

18+
import warnings
1819
from datetime import datetime
1920
from ipaddress import ip_address
2021

@@ -407,7 +408,11 @@ def test_mget_ignores_missing_docs_when_missing_param_is_skip(data_client):
407408
def test_update_works_from_search_response(data_client):
408409
elasticsearch_repo = Repository.search().execute()[0]
409410

410-
elasticsearch_repo.update(owner={"other_name": "elastic"})
411+
with warnings.catch_warnings(record=True) as w:
412+
elasticsearch_repo.update(owner={"other_name": "elastic"})
413+
assert [
414+
str(x.message) for x in w if issubclass(x.category, DeprecationWarning)
415+
] == []
411416
assert "elastic" == elasticsearch_repo.owner.other_name
412417

413418
new_version = Repository.get("elasticsearch-dsl-py")
@@ -442,7 +447,12 @@ def test_save_updates_existing_doc(data_client):
442447

443448
elasticsearch_repo.new_field = "testing-save"
444449
old_seq_no = elasticsearch_repo.meta.seq_no
445-
assert "updated" == elasticsearch_repo.save()
450+
451+
with warnings.catch_warnings(record=True) as w:
452+
assert "updated" == elasticsearch_repo.save()
453+
assert [
454+
str(x.message) for x in w if issubclass(x.category, DeprecationWarning)
455+
] == []
446456

447457
new_repo = data_client.get(index="git", id="elasticsearch-dsl-py")
448458
assert "testing-save" == new_repo["_source"]["new_field"]

tests/test_integration/test_index.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
# specific language governing permissions and limitations
1616
# under the License.
1717

18+
import warnings
19+
1820
from elasticsearch_dsl import Date, Document, Index, IndexTemplate, Text, analysis
1921

2022

@@ -65,7 +67,12 @@ def test_index_can_be_created_with_settings_and_mappings(write_client):
6567
i = Index("test-blog", using=write_client)
6668
i.document(Post)
6769
i.settings(number_of_replicas=0, number_of_shards=1)
68-
i.create()
70+
71+
with warnings.catch_warnings(record=True) as w:
72+
i.create()
73+
assert [
74+
str(x.message) for x in w if issubclass(x.category, DeprecationWarning)
75+
] == []
6976

7077
assert {
7178
"test-blog": {

tests/test_integration/test_search.py

+13
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
from __future__ import unicode_literals
2020

21+
import warnings
22+
2123
from elasticsearch import TransportError
2224
from pytest import raises
2325

@@ -169,3 +171,14 @@ def test_raw_subfield_can_be_used_in_aggs(data_client):
169171
authors = r.aggregations.authors
170172
assert 1 == len(authors)
171173
assert {"key": "Honza Král", "doc_count": 52} == authors[0]
174+
175+
176+
def test_no_deprecation_warnings(data_client):
177+
s = Search(index="git")[0:0]
178+
s.aggs.bucket("authors", "terms", field="author.name.raw", size=1)
179+
180+
with warnings.catch_warnings(record=True) as w:
181+
s.execute()
182+
assert [
183+
str(x.message) for x in w if issubclass(x.category, DeprecationWarning)
184+
] == []

tests/test_search.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from pytest import raises
2121

2222
from elasticsearch_dsl import Document, Q, query, search
23+
from elasticsearch_dsl.connections import CLIENT_HAS_NAMED_BODY_PARAMS
2324
from elasticsearch_dsl.exceptions import IllegalOperation
2425

2526

@@ -43,7 +44,10 @@ def test_cache_can_be_ignored(mock_client):
4344
s._response = r
4445
s.execute(ignore_cache=True)
4546

46-
mock_client.search.assert_called_once_with(index=None, body={})
47+
if CLIENT_HAS_NAMED_BODY_PARAMS:
48+
mock_client.search.assert_called_once_with(index=None)
49+
else:
50+
mock_client.search.assert_called_once_with(index=None, body={})
4751

4852

4953
def test_iter_iterates_over_hits():
@@ -411,7 +415,10 @@ def test_params_being_passed_to_search(mock_client):
411415
s = s.params(routing="42")
412416
s.execute()
413417

414-
mock_client.search.assert_called_once_with(index=None, body={}, routing="42")
418+
if CLIENT_HAS_NAMED_BODY_PARAMS:
419+
mock_client.search.assert_called_once_with(index=None, routing="42")
420+
else:
421+
mock_client.search.assert_called_once_with(index=None, body={}, routing="42")
415422

416423

417424
def test_source():

0 commit comments

Comments
 (0)