prom icon indicating copy to clipboard operation
prom copied to clipboard

Have a catch-all setting on the model

Open Jaymon opened this issue 4 years ago • 0 comments

by default, if you set a property on the Orm that isn't defined in the schema it will just be set on that instance of the Orm, it would be cool to make that so these get saved into a JsonField or something in the table, we have done things like this in the past:

class Foo(Orm):
    bar = Field(str, True)
    catch = JsonField(False)

    @classmethod
    def create(cls, fields=None, **fields_kwargs):
        kwargs = cls.make_dict(fields, fields_kwargs)

        # find all the passed in fields that should be in the catch-all dict
        catch_fields = kwargs.pop("catch", {})
        for k, v in kwargs.items():
            if k in cls.schema.fields: continue
            if "{}_hash".format(k) in cls.schema.fields: continue
            catch_fields[k] = v
        kwargs["catch"] = catch_fields

        return super(Foo, cls).create(kwargs)

Another option that would still allow undefined schema properties to only be set on the instance, you could define catch-all fields like this:

class Foo(Orm):
    catch = [
        "bar",
        "che",
        "baz"
    ]

And only the fields defined in catch would be saved into the db.

The idea is these would be transparently added to the db, so you would still be able to get/set them like any other fields, bonus points if they could also have fset/fget/iset/iget hooks also, and maybe one more, an imissing hook that would be run if the value isn't there.

Another way these could be defined is through a different Field instance:

class Foo(Orm):
    bar = Field(str, True)
    che = CatchField(str, True)
    baz = CatchField(bool, False)

So, in the above example, bar would be a normal field and che and baz would be placed into a catch-all field.

The one downside to defining them is it makes it harder to just willy-nilly add fields, which is what this is used for, so the best way to do it might be to have it be a real catch-all with the option of defining some of the fields if needed, but if the fields aren't defined they would still be saved to the catch all field, this would require doing something like setting catch=True on the orm.

Jaymon avatar Dec 05 '19 22:12 Jaymon