prom
prom copied to clipboard
Have a catch-all setting on the model
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.