Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Support pyelasticsearch 0.4 change (closes #759)
pyelasticsearch 0.4 removed the `to_python` method Haystack used.

Thanks to @erikrose for the quick patch
  • Loading branch information
acdha committed Mar 20, 2013
1 parent 46b8117 commit 8e86909
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 3 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Expand Up @@ -67,3 +67,4 @@ Thanks to
* Rodrigo Guzman (rz) for a fix to query handling in the ``simple`` backend.
* Martin J. Laubach (mjl) for fixing the logic used when combining querysets
* Eric Holscher (ericholscher) for a docs fix.
* Erik Rose (erikrose) for a quick pyelasticsearch-compatibility patch
2 changes: 1 addition & 1 deletion docs/backend_support.rst
Expand Up @@ -50,7 +50,7 @@ Elasticsearch
* Stored (non-indexed) fields
* Highlighting
* Spatial search
* Requires: pyelasticsearch 0.2+ & Elasticsearch 0.17.7+
* Requires: pyelasticsearch 0.4+ & Elasticsearch 0.17.7+

Whoosh
------
Expand Down
45 changes: 44 additions & 1 deletion haystack/backends/elasticsearch_backend.py
@@ -1,4 +1,5 @@
import datetime
import re
import warnings
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
Expand All @@ -22,6 +23,11 @@
raise MissingDependency("The 'elasticsearch' backend requires the installation of 'pyelasticsearch'. Please refer to the documentation.")


DATETIME_REGEX = re.compile(
r'^(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})T'
r'(?P<hour>\d{2}):(?P<minute>\d{2}):(?P<second>\d{2})(\.\d+)?$')


class ElasticsearchSearchBackend(BaseSearchBackend):
# Word reserved by Elasticsearch for special use.
RESERVED_WORDS = (
Expand Down Expand Up @@ -583,7 +589,7 @@ def _process_results(self, raw_results, highlight=False,
if string_key in index.fields and hasattr(index.fields[string_key], 'convert'):
additional_fields[string_key] = index.fields[string_key].convert(value)
else:
additional_fields[string_key] = self.conn.to_python(value)
additional_fields[string_key] = self._to_python(value)

del(additional_fields[DJANGO_CT])
del(additional_fields[DJANGO_ID])
Expand Down Expand Up @@ -666,6 +672,43 @@ def build_schema(self, fields):

return (content_field_name, mapping)

def _to_python(self, value):
"""Convert values from ElasticSearch to native Python values."""
if isinstance(value, (int, float, complex, list, tuple, bool)):
return value

if isinstance(value, basestring):
possible_datetime = DATETIME_REGEX.search(value)

if possible_datetime:
date_values = possible_datetime.groupdict()

for dk, dv in date_values.items():
date_values[dk] = int(dv)

return datetime(
date_values['year'], date_values['month'],
date_values['day'], date_values['hour'],
date_values['minute'], date_values['second'])

try:
# This is slightly gross but it's hard to tell otherwise what the
# string's original type might have been. Be careful who you trust.
converted_value = eval(value)

# Try to handle most built-in types.
if isinstance(
converted_value,
(int, list, tuple, set, dict, float, complex)):
return converted_value
except Exception:
# If it fails (SyntaxError or its ilk) or we don't trust it,
# continue on.
pass

return value



# Sucks that this is almost an exact copy of what's in the Solr backend,
# but we can't import due to dependencies.
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Expand Up @@ -8,7 +8,7 @@ deps =
pysolr
poster
whoosh
pyelasticsearch
pyelasticsearch>=0.4
httplib2
python-dateutil
geopy
Expand Down

0 comments on commit 8e86909

Please sign in to comment.