mutable extension problems sa-0.7.9

23 views
Skip to first unread message

Dmitry Bogun

unread,
Dec 4, 2012, 6:26:09 AM12/4/12
to sqlal...@googlegroups.com
I have tried to create some custom SA type. And got in situation when I can't find correct wayout. Minimal test case in attach.

My app have class SiteVersion, it can be used as regular object and as SA mmaped object. When I use only SiteVesionDeco(see attach) all works fine, except propagating updates to DB. When I have tried to add SiteVersionWatch, everything failed down:

$ ~/tmp/z/z.py
2012-12-04 13:15:10,134 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("my_data")
2012-12-04 13:15:10,134 INFO sqlalchemy.engine.base.Engine ()
2012-12-04 13:15:10,134 INFO sqlalchemy.engine.base.Engine
CREATE TABLE my_data (
    id INTEGER NOT NULL,
    data VARCHAR,
    PRIMARY KEY (id)
)


2012-12-04 13:15:10,135 INFO sqlalchemy.engine.base.Engine ()
2012-12-04 13:15:10,135 INFO sqlalchemy.engine.base.Engine COMMIT
2012-12-04 13:15:10,135 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2012-12-04 13:15:10,136 INFO sqlalchemy.engine.base.Engine INSERT INTO my_data (data) VALUES (?)
2012-12-04 13:15:10,136 INFO sqlalchemy.engine.base.Engine ('1.0',)
2012-12-04 13:15:10,136 INFO sqlalchemy.engine.base.Engine COMMIT
2012-12-04 13:15:10,137 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2012-12-04 13:15:10,137 INFO sqlalchemy.engine.base.Engine SELECT my_data.id AS my_data_id, my_data.data AS my_data_data
FROM my_data
WHERE my_data.id = ?
2012-12-04 13:15:10,137 INFO sqlalchemy.engine.base.Engine (1,)
2012-12-04 13:15:10,137 INFO sqlalchemy.engine.base.Engine ROLLBACK
Traceback (most recent call last):
  File "/home/surabujin/tmp/z/z.py", line 172, in <module>
    main()
  File "/home/surabujin/tmp/z/z.py", line 169, in main
    dbs.commit()
  File "/home/surabujin/devel/DORS/env/local/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 703, in commit
    self.transaction.commit()
  File "/home/surabujin/devel/DORS/env/local/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 361, in commit
    self._prepare_impl()
  File "/home/surabujin/devel/DORS/env/local/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 340, in _prepare_impl
    self.session.flush()
  File "/home/surabujin/devel/DORS/env/local/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 1718, in flush
    self._flush(objects)
  File "/home/surabujin/devel/DORS/env/local/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 1789, in _flush
    flush_context.execute()
  File "/home/surabujin/devel/DORS/env/local/lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.py", line 331, in execute
    rec.execute(self)
  File "/home/surabujin/devel/DORS/env/local/lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.py", line 475, in execute
    uow
  File "/home/surabujin/devel/DORS/env/local/lib/python2.7/site-packages/sqlalchemy/orm/persistence.py", line 54, in save_obj
    table, states_to_update)
  File "/home/surabujin/devel/DORS/env/local/lib/python2.7/site-packages/sqlalchemy/orm/persistence.py", line 326, in _collect_update_commands
    attributes.PASSIVE_NO_INITIALIZE)
  File "/home/surabujin/devel/DORS/env/local/lib/python2.7/site-packages/sqlalchemy/orm/attributes.py", line 1249, in get_state_history
    return state.get_history(key, passive)
  File "/home/surabujin/devel/DORS/env/local/lib/python2.7/site-packages/sqlalchemy/orm/state.py", line 104, in get_history
    return self.manager[key].impl.get_history(self, self.dict, passive)
  File "/home/surabujin/devel/DORS/env/local/lib/python2.7/site-packages/sqlalchemy/orm/attributes.py", line 533, in get_history
    self, state, dict_.get(self.key, NO_VALUE))
  File "/home/surabujin/devel/DORS/env/local/lib/python2.7/site-packages/sqlalchemy/orm/attributes.py", line 1150, in from_scalar_attribute
    elif attribute.is_equal(current, original) is True:
  File "/home/surabujin/devel/DORS/env/local/lib/python2.7/site-packages/sqlalchemy/types.py", line 750, in compare_values
    return self.impl.compare_values(x, y)
  File "/home/surabujin/devel/DORS/env/local/lib/python2.7/site-packages/sqlalchemy/types.py", line 84, in compare_values
    return x == y
  File "/home/surabujin/tmp/z/z.py", line 77, in __eq__
    raise NotImplementedError('Expect %s instance, got %s' % (SiteVersion, other))
NotImplementedError: Expect <class '__main__.SiteVersion'> instance, got <symbol 'NO_VALUE>

Why it try to make SA specific comparison before converting object into built-in type String? How can I fix it?
z.py

Michael Bayer

unread,
Dec 4, 2012, 10:35:27 AM12/4/12
to sqlal...@googlegroups.com
this is an incorrect __eq__() method:

    def __eq__(self, other):
        if not isinstance(other, SiteVersion):
            raise NotImplementedError('Expect %s instance, got %s' % (SiteVersion, other))

suppose I have a custom object Foo:

class Foo(object):
    def __eq__(self, other):
        return other is self

then I make one:

f = Foo()

is it not valid to say this ?

>>> f == 5
False

therefore __eq__() cannot raise an exception if the incoming object is of a different type.

a simple change:

    def __eq__(self, other):
        if not isinstance(other, SiteVersion):
            return False

and your script runs fine.



--
You received this message because you are subscribed to the Google Groups "sqlalchemy" group.
To view this discussion on the web visit https://groups.google.com/d/msg/sqlalchemy/-/Cdl5FTQOAE0J.
To post to this group, send email to sqlal...@googlegroups.com.
To unsubscribe from this group, send email to sqlalchemy+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
<z.py>

Dmitry Bogun

unread,
Dec 4, 2012, 11:22:46 AM12/4/12
to sqlal...@googlegroups.com
Sorry, my fault. I was not enough attentive while read this http://docs.python.org/2.7/reference/datamodel.html?highlight=__eq__#object.__eq__ part of documentation. I somehow thought that comparison method must wait NotImplementedError in case of impassible comparison. But now, when you point me on my error I see, that documentation say about returgnin NotImplemented singleton, from not implemented comparison methods.

Sorry, I very ashamed. Thanks for clarification.

PS Is there a more simpler method to mark an attribute of mapped instance as "dirty"?
Reply all
Reply to author
Forward
0 new messages