josiahcarlson/rom

Model sharing data between two instances

Closed this issue · 3 comments

Using python 3.8.

I'm noticing that this code:

import rom

rom.util.set_connection_settings(host='localhost', port=16379, db=2)

class Foo(rom.Model):
    id = rom.PrimaryKey(index=True)
    field1 = rom.Text(required=True)
    field2 = rom.Json(default=[])

foo1 = Foo(field1='bob')
foo1.field2.append({'hello': 'world'})
print(foo1.id, foo1.field1, foo1.field2)
foo1.save()

foo2 = Foo(field1='sam')
print(foo2.id, foo2.field1, foo2.field2)

produces this output:

9 bob [{'hello': 'world'}]
10 sam [{'hello': 'world'}]

Expected behavior would be that entity 'sam' would have an empty field2.

Am I using it incorrectly?

Note that my workaround is just to use a callable for field2's default, a function that returns [].

Hello and thank you for your question. Yes, indeed, you need to use a callable as a default. Rom does no more magic to your defaults than Python, so just like Python shares lists as default arguments, so does rom. Here is an example that completely excludes rom, yet demonstrates identical behavior.

def foo(value, default=[]):
    default.append(value)
    return default

a = foo(1)
b = foo(2)
print(a, b)

Am I using it incorrectly?

Yes, you need to use default=list if you need a list, or similar, like you've found.

Also, you'll find that updating those values is tough UNLESS you explicitly set the value:

a = Foo(field1='blah')
# These do nothing except modify in-process values!
a.field2.append({"key": "value"})
a.save()
# WARNING: the above did NOTHING to remote rom / Redis data!

# let's get fresh data from Redis:
a.refresh(force=True)

# YOU MUST *set* the attribute to something *new* to get rom to recognize the change:
a.field2 = a.field2 + [{"key": "value"}]
a.save()
# NOW your data is saved

Note: I added json for flexibility with storing arbitrary data, and I need to update the docs to reflect the above requirements. Also note that json columns are the only mutable columns; all other values are immutable, so require setting in some way to update, so this generally doesn't come up.

Understood, thank you!