question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Persisting Nested Objects

See original GitHub issue

Note: Cross-posting from http://discuss.elastic.co. Not sure where is better for elasticsearch-dsl questions.

I’m attempting to persist an object to elasticsearch with a nested object. However instead of using syntax like:

child = field.Object(properties={'name': field.String()})

I’d like to have child be it’s own object.

from elasticsearch_dsl import field, document
from elasticsearch_dsl import connections
connections.connections.create_connection(hosts=['localhost'], timeout=20)


class Child(field.Object):
    name = field.String()


class Parent(document.DocType):
    name = field.String()
    child = Child()

    class Meta:
        index = 'myindex'

parent = Parent(name='test parent')
parent.child = Child(name='test other child')
parent.save()

However, doing it this way results in:

  File "/home/abarilla/PycharmProjects/iocdb/iocdb/model/test.py", line 25, in <module>
    parent.child = Child(name='test other child')
  File "/home/abarilla/.virtualenvs/iocdb/local/lib/python2.7/site-packages/elasticsearch_dsl/document.py", line 115, in __setattr__
    return super(DocType, self).__setattr__(name, value)
  File "/home/abarilla/.virtualenvs/iocdb/local/lib/python2.7/site-packages/elasticsearch_dsl/utils.py", line 418, in __setattr__
    value = self._doc_type.mapping[name].to_python(value)
  File "/home/abarilla/.virtualenvs/iocdb/local/lib/python2.7/site-packages/elasticsearch_dsl/field.py", line 63, in to_python
    return self._to_python(data)
  File "/home/abarilla/.virtualenvs/iocdb/local/lib/python2.7/site-packages/elasticsearch_dsl/field.py", line 133, in _to_python
    return self._doc_class(self.properties, **data)
TypeError: type object argument after ** must be a mapping, not Child

Is there a way I can accomplish this?

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Comments:14 (4 by maintainers)

github_iconTop GitHub Comments

6reactions
JoshCoadycommented, Apr 5, 2017

I wasn’t sure if this warranted a new issue, but along these same lines, it seems like currently you need to define your classes like this:

class OrderItem(InnerObjectWrapper):
    pass

class Order(DocType):
    items = Object(
        doc_class=OrderItem,
        multi=True,
        properties={
            'description': Text(),
            'quantity': Integer(),
            'price': Float()
        }
    )

You don’t actually need the OrderItem class if you aren’t going to customize it. You could just set doc_type=InnerObjectWrapper, but I included it this way so that the examples are consistent.

Where I’d prefer to be able to define them more like this:

class OrderItem(InnerObjectWrapper):
    description = Text()
    quantity = Integer()
    price = Float()

class Order(DocType):
    items = Object(
        doc_class=OrderItem,
        multi=True
    )

In this way the properties definitions for inner objects is consistent with that of the top level. It also allows you to keep your field definitions with the object it belongs to, reducing coupling and allowing for inner objects that could be reusable without having to duplicate the properties definition in every using class.

For example, say you have a CMS with an index for each type of content like articles, slideshows, and quizzes, etc. But each of those documents may want to have an author sub object. If the properties are set where they naturally belong (on the author class) then you don’t need do duplicate that code to all of the different content type doc classes.

class Author(InnerObjectWrapper):
    name = Text()
    image_url = Text()
    bio_url = Text()

Is there maybe a way to do this that I’m missing or is it on the roadmap or do I just need to use properties for inner objects?

3reactions
gilbsgilbscommented, Oct 9, 2017

I agree with @JoshCoady . The current way to define Nested objects is quite inconsistent and counter-intuitive. It also prevents reusability of nested objects. I think there should be virtually no difference between nested objects and inner objects from the ORM perspective, apart from the way you declare them:

class OrderItem(InnerObject):
    description = Text()
    quantity = Integer()
    price = Float()

class Order(DocType):
    items = Nested(doc_class=OrderItem)
    # or
    items = OrderItem(multi=True)

Let’s say I want to denormalize the last item, I’d like to be able to do something like this:

class Order(DocType):
    items = Nested(doc_class=OrderItem)
    last_item = OrderItem()

Currently, I have to duplicate the OrderItem object to be able to do this, and this is very ugly. Or I missed something?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why do I have to persist both objects if Address is nested in ...
Try the cascade element for the annotation. @OneToMany(fetch=FetchType.LAZY, mappedBy="user", cascade=CascadeType.PERSIST) private ...
Read more >
Persisting complex Embeddable/Embedded objects in Spring ...
Hibernate defines two general types of objects, the Entity type being what ... This is called Nesting and according to the Java Persistence...
Read more >
Persisting and hydrating nested/non-nested class objects-lists ...
I'm having problems persisting lists of class objects-lists-maps (in a few cases those are nested with other class objects-lists-maps).
Read more >
Spring JPA – persisting nested objects - iTecNote
I have a simple JPA repository that looks like this: public interface UserRepository extends JpaRepository<User, String> { User findByName(String name); }.
Read more >
Object States in Hibernate's Session - Baeldung
An object that we've associated with a session is in the persistent state. We either saved it or read it from a persistence...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found