[sqlalchemy] onupdate Column attribute with joined table inheritance question
Hi all, I am having a problem that is identical to the one mentioned last year on this list: http://groups.google.com/group/sqlalchemy/browse_thread/thread/efd3993c94c8d162/37943cda02151f2b?lnk=gstq=onupdate+inheritance#37943cda02151f2b I have Engineer and Manager tables that are inheriting from an Employee table using joined table inheritance. When I update one of the child tables, I want the last_edited timestamp column on the Employee table to be updated as well, but it is not updating. Mr. Bayer proposes the following: from sqlalchemy.orm import mapper as _mapper from sqlalchemy.orm import MapperExtension class MyExt(MapperExtension): def before_update(self, mapper, connection, instance): if hasattr(instance, '__before_update__'): instance.__before_update__() def mapper(*args, **kw): kw['extension'] = MyExt() return _mapper(*args, **kw) just hide that code away someplace, and then any instance which defines a method called __before_update__() will have it called before update. I've done that step, but I don't understand what the next step is. I thought that I would have to implement a __before_update__ method on my Engineer and Manager classes, which would then call some method on Employee using super. However, when I update my Engineer, it doesn't even look like the __before_update__ method is being called. So I conclude that I'm doing it wrong.Which instances should implement a __before_update__ method? What should the __before_update__ method do? Any advice would be extremely appreciated. Thanks, John --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: onupdate Column attribute with joined table inheritance question
On Mar 2, 2009, at 2:16 PM, John Fries wrote: Hi all, I am having a problem that is identical to the one mentioned last year on this list: http://groups.google.com/group/sqlalchemy/browse_thread/thread/efd3993c94c8d162/37943cda02151f2b?lnk=gstq=onupdate+inheritance#37943cda02151f2b I have Engineer and Manager tables that are inheriting from an Employee table using joined table inheritance. When I update one of the child tables, I want the last_edited timestamp column on the Employee table to be updated as well, but it is not updating. Mr. Bayer proposes the following: from sqlalchemy.orm import mapper as _mapper from sqlalchemy.orm import MapperExtension class MyExt(MapperExtension): def before_update(self, mapper, connection, instance): if hasattr(instance, '__before_update__'): instance.__before_update__() def mapper(*args, **kw): kw['extension'] = MyExt() return _mapper(*args, **kw) just hide that code away someplace, and then any instance which defines a method called __before_update__() will have it called before update. I've done that step, but I don't understand what the next step is. I thought that I would have to implement a __before_update__ method on my Engineer and Manager classes, which would then call some method on Employee using super. However, when I update my Engineer, it doesn't even look like the __before_update__ method is being called. So I conclude that I'm doing it wrong.Which instances should implement a __before_update__ method? What should the __before_update__ method do? just implement def __before_update__() on your base Employee class. this method should set the last_edited attribute to a new value (note you can set it to func.now() to have a SQL function fire off). Engineer and Manager will have the method automatically via class inheritance. Also make sure you are using the modfied mapper() function to create your mappers. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: onupdate Column attribute with joined table inheritance question
Thanks Michael! That should have been obvious to me, but for some reason I couldn't figure it out. On Mon, Mar 2, 2009 at 11:24 AM, Michael Bayer mike...@zzzcomputing.comwrote: On Mar 2, 2009, at 2:16 PM, John Fries wrote: Hi all, I am having a problem that is identical to the one mentioned last year on this list: http://groups.google.com/group/sqlalchemy/browse_thread/thread/efd3993c94c8d162/37943cda02151f2b?lnk=gstq=onupdate+inheritance#37943cda02151f2b I have Engineer and Manager tables that are inheriting from an Employee table using joined table inheritance. When I update one of the child tables, I want the last_edited timestamp column on the Employee table to be updated as well, but it is not updating. Mr. Bayer proposes the following: from sqlalchemy.orm import mapper as _mapper from sqlalchemy.orm import MapperExtension class MyExt(MapperExtension): def before_update(self, mapper, connection, instance): if hasattr(instance, '__before_update__'): instance.__before_update__() def mapper(*args, **kw): kw['extension'] = MyExt() return _mapper(*args, **kw) just hide that code away someplace, and then any instance which defines a method called __before_update__() will have it called before update. I've done that step, but I don't understand what the next step is. I thought that I would have to implement a __before_update__ method on my Engineer and Manager classes, which would then call some method on Employee using super. However, when I update my Engineer, it doesn't even look like the __before_update__ method is being called. So I conclude that I'm doing it wrong.Which instances should implement a __before_update__ method? What should the __before_update__ method do? just implement def __before_update__() on your base Employee class. this method should set the last_edited attribute to a new value (note you can set it to func.now() to have a SQL function fire off). Engineer and Manager will have the method automatically via class inheritance. Also make sure you are using the modfied mapper() function to create your mappers. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Weird mapper() behaviour (bug?)
Hi guys! Here goes the code sample: from sqlalchemy import create_engine, MetaData from sqlalchemy import Table, Column, ForeignKey, Integer from sqlalchemy.orm import sessionmaker, mapper, relation metadata = MetaData() engine = create_engine('sqlite:///:memory:', echo=True) parent_table = Table('parent', metadata, Column('id', Integer, primary_key=True)) child_table = Table('child', metadata, Column('id', Integer, primary_key=True), Column('parent_id', Integer, ForeignKey('parent.id'))) class Parent(object): pass class Child(object): pass mapper(Parent, parent_table, properties={'children': relation(Child, backref=u'parent')}) mapper(Child, child_table) metadata.create_all(engine) session = sessionmaker(bind=engine)() parentobj = Parent() Running this code fails with this error: .../SQLAlchemy-0.5.2-py2.6.egg/sqlalchemy/orm/properties.pyc in _post_init(self) 993 994 if self.backref is not None: -- 995 self.backref.compile(self) 996 elif not mapper.class_mapper(self.parent.class_, compile=False)._get_property(self.key, raiseerr=False): 997 raise sa_exc.ArgumentError(Attempting to assign a new relation '%s' to AttributeError: 'unicode' object has no attribute 'compile' This line is the problem: mapper(Parent, parent_table, properties={'children': relation (Child, backref=u'parent')}) or, to be precise, `backref=u'parent'`. With just `backref='parent'`, everything works just fine, it breaks down when using a unicode literal for backref name. Is this a bug, or somehow expected behavior? Thanks everyone... --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: Weird mapper() behaviour (bug?)
its a bug, there's an isinstance(str) that should be isinstance(basestring). please file a trac ticket. On Mar 2, 2009, at 6:26 PM, Karlo Lozovina wrote: Hi guys! Here goes the code sample: from sqlalchemy import create_engine, MetaData from sqlalchemy import Table, Column, ForeignKey, Integer from sqlalchemy.orm import sessionmaker, mapper, relation metadata = MetaData() engine = create_engine('sqlite:///:memory:', echo=True) parent_table = Table('parent', metadata, Column('id', Integer, primary_key=True)) child_table = Table('child', metadata, Column('id', Integer, primary_key=True), Column('parent_id', Integer, ForeignKey('parent.id'))) class Parent(object): pass class Child(object): pass mapper(Parent, parent_table, properties={'children': relation(Child, backref=u'parent')}) mapper(Child, child_table) metadata.create_all(engine) session = sessionmaker(bind=engine)() parentobj = Parent() Running this code fails with this error: .../SQLAlchemy-0.5.2-py2.6.egg/sqlalchemy/orm/properties.pyc in _post_init(self) 993 994 if self.backref is not None: -- 995 self.backref.compile(self) 996 elif not mapper.class_mapper(self.parent.class_, compile=False)._get_property(self.key, raiseerr=False): 997 raise sa_exc.ArgumentError(Attempting to assign a new relation '%s' to AttributeError: 'unicode' object has no attribute 'compile' This line is the problem: mapper(Parent, parent_table, properties={'children': relation (Child, backref=u'parent')}) or, to be precise, `backref=u'parent'`. With just `backref='parent'`, everything works just fine, it breaks down when using a unicode literal for backref name. Is this a bug, or somehow expected behavior? Thanks everyone... --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: Weird mapper() behaviour (bug?)
On Mar 3, 1:03 am, Michael Bayer mike...@zzzcomputing.com wrote: its a bug, there's an isinstance(str) that should be isinstance(basestring). please file a trac ticket. Done, here it is: http://www.sqlalchemy.org/trac/ticket/1330 -- Karlo Lozovina --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: export and import JSON from database (JSON type)
On Feb 28, 10:50 am, Michael Bayer mike...@zzzcomputing.com wrote: A method like this would work: def from_json(self,json): json_obj = simplejson.loads(json) for k, v in json_obj.values(): setattr(self, k, v) if you're concerned about dates you can use a date-based TypeDecorator which can receive a fully qualified datestring as an argument. Or use descriptors on your mapped classes (i.e. date = property(def get_date()/def set_date())) Thanks for the code example, setattr() was exactly what I was looking for! I did have to make a minor change; I initially got this error: for k, v in json_obj.values(): ValueError: too many values to unpack but was OK once I made the change to: for k, v in json_obj.iteritems(): setattr(self, k, v) Thanks also for the hint to look at TypeDecorator and descriptors. I was surprised to find that just passing the default attribute types/ values of comment after the setattr() calls via session.save (comment) actually worked, since the postdate attribute on the comment class instance had a type of unicode. I was expecting to have to handle changing this to a datetime type in order to get it to work. Am I right in guessing that this works because the underlying database (PostgreSQL) recognized the unicode date string and was able to convert it, or is SA doing something for me with its internal type engine/system in conjunction with the db (i.e. in other words, I'm trying to figure out what component is making this work so I know where to look for what's considered a legal/well-formed/importable javascript date string)? Thanks again for all of the help, -e --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Infinite recursion in sqlalchemy/orm/attributes.py when running under debugger
Hi, I have a table-mapped attribute that is dependent on two other attributes: from sqlalchemy import Table, MetaData, Column, Text, create_engine, Integer from sqlalchemy.orm import mapper, synonym class Foo(object): def _get_name(self): return self._name def _set_name(self, name): self._name = name self._update_table_name() name = property(_get_name, _set_name) def _get_provider(self): return self._provider def _set_provider(self, provider): self._provider = provider self._update_table_name() provider = property(_get_provider, _set_provider) def _update_table_name(self): table_name = %s_%s % (self.provider, self.name) if len(table_name) 50: table_name = table_name[0:50] self.table_name = table_name foo_table = Table('foo', MetaData(), Column('id', Integer, primary_key=True), Column('name', Text), Column('provider', Text), Column('table_name', Text) ) mapper(Foo, foo_table, properties={ 'name' : synonym('_name', map_column=True), 'provider': synonym('_provider', map_column=True), }) e = create_engine('sqlite:///:memory:') foo_table.metadata.create_all(bind=e) When I run this normally, nothing happens. When I run it under the debugger (in PyDev), I get infinite recursion, looking like this: Traceback (most recent call last): File /Applications/eclipse/plugins/ org.python.pydev.debug_1.4.4.2636/pysrc/pydevd.py, line 883, in module debugger.run(setup['file'], None, None) File /Applications/eclipse/plugins/ org.python.pydev.debug_1.4.4.2636/pysrc/pydevd.py, line 712, in run execfile(file, globals, locals) #execute the script File /Users/gthb/Documents/workspace/test/src/sqlalchemytest7.py, line 33, in module 'provider': synonym('_provider', map_column=True), File /path/to/SQLAlchemy/sqlalchemy/orm/__init__.py, line 752, in mapper return Mapper(class_, local_table, *args, **params) File /path/to/SQLAlchemy/sqlalchemy/orm/mapper.py, line 198, in __init__ self._configure_properties() File /path/to/SQLAlchemy/sqlalchemy/orm/mapper.py, line 481, in _configure_properties self._configure_property(key, prop, False) File /path/to/SQLAlchemy/sqlalchemy/orm/mapper.py, line 616, in _configure_property prop.instrument_class(self) File /path/to/SQLAlchemy/sqlalchemy/orm/properties.py, line 302, in instrument_class proxy_property=self.descriptor File /path/to/SQLAlchemy/sqlalchemy/orm/attributes.py, line 1590, in register_descriptor descriptor = proxy_type(key, proxy_property, comparator, parententity) File /path/to/SQLAlchemy/sqlalchemy/orm/attributes.py, line 181, in __init__ self.descriptor = self.user_prop = descriptor File /Users/gthb/Documents/workspace/test/src/sqlalchemytest7.py, line 14, in _set_name self._update_table_name() File /path/to/SQLAlchemy/sqlalchemy/orm/attributes.py, line 214, in __getattr__ return getattr(self._comparator, attribute) File /path/to/SQLAlchemy/sqlalchemy/orm/attributes.py, line 214, in __getattr__ return getattr(self._comparator, attribute) The same can be reproduced outside of PyDev by doing: python -m pdb sqlalchemytest7.py and stepping until the above calamity strikes. (It seems it does not happen on cont) This is in python 2.5.2 on Mac OS X 10.5.6, with sqlalchemy 0.5.2. So, two things: 1) what am I doing wrong? 2) SQLAlchemy should handle it more gracefully. :) Regards, - Gulli --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---