GithubHelp home page GithubHelp logo

ListField not validated on append about umongo HOT 7 OPEN

scille avatar scille commented on May 30, 2024
ListField not validated on append

from umongo.

Comments (7)

lafrech avatar lafrech commented on May 30, 2024

Unless I'm missing something, this is a really blocking issue, as this allows to set invalid data that will not be checked even at commit time.

I could modify List to keep a reference to its parent field and call

    self._parent_field._validate(self)

in set_modified to ensure the field is validated each time the list is modified.

However, this is not satisfying because

  • The validation error will be raised after the data is modified, so if the error is caught, the data is still wrong.

  • This does not address the mutation of a List element. Not sure how this could be addressed.

Or should we live with it? In this case, it would be nice to at least validate the data on commit. I dug a bit into this and I'm afraid it's not easier.

What I can do is add pre_insert / pre_update methods in Doc where I manually validate the values:

self.Schema().fields['l'].validate(self.l)

Is there a better workaround for this?

from umongo.

touilleMan avatar touilleMan commented on May 30, 2024

You're totally right, this is a serious issue.

Worse, I need it to be applied not only when an embedded document is appended to the list, but also when an embedded document in the list is mutated. If the latter is not feasible,

This should be feasible with umongo !

I could modify List to keep a reference to its parent field and call

This seems the right way to do it for me (I fact it was like this in the old versions of umongo, but get removed because... stuff)

I'm thinking of a small rollback system to handle this:

  • each BaseDataObject got a link on it parent (which means there should be swallow copy when reusing them)
  • once a modification order received, the BaseDataObject runs it own validation and raise exception if needed (this is what is done in current version)
  • when the new data has been validated, it set it into it field and call the parent's validator
  • the parent run validation and call it own parent validator
  • this goes up to the Document which runs it own validator
  • if one of the validators got an error, they call on their child a _revert method. This call goes down through the parents to the BaseDataObject.
  • The BaseDataObject has kept track of it change and can easily revert it (if a field is modified keep the old version, if a list is modified, keep the old list)

We can optimize this by only calling the parent validator if it is requested (i.e. almost never)
Another solution would be to use a mechanism of publish/subscribe. This could be cleaner when BaseDataObject are used multiple time across documents/embedded documents, however this bring another dependency (or cumbersome code if we do it ourself).

from umongo.

lafrech avatar lafrech commented on May 30, 2024

I'm glad to hear this should work. Indeed, I realized afterwards that even list elements mutations are catchable since these are not just objects but umongo fields (DictField being an exception to that again). That's great.

Regarding the method, I'm afraid I won't be of much help. I have no specific knowledge of publish/subscribe systems, so I can't provide any relevant advice about it. umongo is growing and it certainly makes sense to make things in a canonical way (I mean following a common pattern, be it with own code or using an external lib) rather than introducing hacks everywhere.

I don't think adding a dependency is an issue by itself. As long as it is reliable in time. Unless I need a very small subset, I find it better to depend on a code shared with other projects than rewriting it.

from umongo.

lafrech avatar lafrech commented on May 30, 2024

Related: del my_document.my_list[i] doesn't mark my_list field as modified. (Fixed in #195)

from umongo.

lafrech avatar lafrech commented on May 30, 2024

This also affects DictField.update and such.

from umongo.

lafrech avatar lafrech commented on May 30, 2024

In fact, reading @touilleMan's comment above, I'm realizing that validators other than field validators, such as schema-level validators are only executed when loading data on object instantiation (__init__ -> schema load), at least not when modifying a single field.

Doing so might be a little bit complicated and add a lot of overhead. We could decide we don't support custom validators such as schema validators.

However, I still think field validators as in OP should be completely supported so this bug still stands.

We could just do the change in the data object, call parent field validator, catch error and rollback the change in a finally clause. This could be simple. But it doesn't work for deeper nesting, like list of lists, or embedded fields,...

from umongo.

zevaryx avatar zevaryx commented on May 30, 2024

I think I'm having an issue related to this in one of my programs. I have the following code, and Roleping.is_modified isn't getting set as True in the following:

class Roleping(Document):
    """Roleping database object."""

    active = fields.BooleanField(default=True)
    role = fields.IntegerField(required=True)
    guild = fields.IntegerField(required=True)
    admin = fields.IntegerField(required=True)
    bypass = fields.DictField()
    created_at = fields.DateTimeField(default=datetime.utcnow)

# in another file while modifying
roleping.bypass["users"].append(bypass.id)  # Does not set is_modified to True

Having a list inside of a dictionary doesn't flag the dictionary as having been updated

from umongo.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.