Repository: elastic/elasticsearch-dsl-py

Issue:
Datetimes dropping miliseconds
The problems causes dates like '1970-01-01T00:17:47.045Z' in ElasticSearch to end up as a datetime like
datetime.datetime(1970, 1, 1, 0, 17, 47)                                                                                        

My expectation is that this value should produce a datetime like
datetime.datetime(1970, 1, 1, 0, 17, 47, 45000)

https://github.com/elastic/elasticsearch-dsl-py/blob/269fef7fa12333f7622c3694df75a1b296d87ae2/elasticsearch_dsl/field.py#L221

This is caused by integer division on the line referenced above. Changing this line to divide by 1000.0 fixes the issue. 




Discussion:

Patch:
diff --git a/elasticsearch_dsl/analysis.py b/elasticsearch_dsl/analysis.py
index 8424283..c2abd94 100644
--- a/elasticsearch_dsl/analysis.py
+++ b/elasticsearch_dsl/analysis.py
@@ -19,9 +19,9 @@ class AnalysisBase(object):
 
 class CustomAnalysis(object):
     name = 'custom'
-    def __init__(self, name, builtin_type='custom', **kwargs):
+    def __init__(self, filter_name, builtin_type='custom', **kwargs):
         self._builtin_type = builtin_type
-        self._name = name
+        self._name = filter_name
         super(CustomAnalysis, self).__init__(**kwargs)
 
     def to_dict(self):
diff --git a/elasticsearch_dsl/faceted_search.py b/elasticsearch_dsl/faceted_search.py
index 795132f..129b4fc 100644
--- a/elasticsearch_dsl/faceted_search.py
+++ b/elasticsearch_dsl/faceted_search.py
@@ -145,7 +145,8 @@ class DateHistogramFacet(Facet):
             # so we need to set key to 0 to avoid TypeError exception
             if bucket['key'] is None:
                 bucket['key'] = 0
-            return datetime.utcfromtimestamp(int(bucket['key']) / 1000)
+            # Preserve milliseconds in the datetime
+            return datetime.utcfromtimestamp(int(bucket['key']) / 1000.0)
         else:
             return bucket['key']
 
diff --git a/elasticsearch_dsl/field.py b/elasticsearch_dsl/field.py
index 129b53c..d895e7e 100644
--- a/elasticsearch_dsl/field.py
+++ b/elasticsearch_dsl/field.py
@@ -218,7 +218,8 @@ class Date(Field):
         if isinstance(data, date):
             return data
         if isinstance(data, int):
-            return datetime.utcfromtimestamp(data / 1000)
+            # Divide by a float to preserve milliseconds on the datetime.
+            return datetime.utcfromtimestamp(data / 1000.0)
 
         try:
             # TODO: add format awareness


Test patch:
diff --git a/test_elasticsearch_dsl/test_analysis.py b/test_elasticsearch_dsl/test_analysis.py
index 014c43d..6dc3c09 100644
--- a/test_elasticsearch_dsl/test_analysis.py
+++ b/test_elasticsearch_dsl/test_analysis.py
@@ -79,3 +79,11 @@ def test_custom_analyzer_can_collect_custom_items():
         }
     } == a.get_analysis_definition()
 
+def test_stemmer_analyzer_can_pass_name():
+    t = analysis.token_filter('my_english_filter', name="minimal_english", type="stemmer")
+    assert t.to_dict() == 'my_english_filter'
+    assert {
+        "type" : "stemmer",
+        "name" : "minimal_english"
+    } == t.get_definition()
+