[sqlalchemy] onupdate Column attribute with joined table inheritance question

2009-03-02 Thread John Fries
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

2009-03-02 Thread Michael Bayer

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

2009-03-02 Thread John Fries
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?)

2009-03-02 Thread Karlo Lozovina

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?)

2009-03-02 Thread Michael Bayer

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?)

2009-03-02 Thread Karlo Lozovina

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)

2009-03-02 Thread eLuke

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

2009-03-02 Thread Gunnlaugur Briem

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
-~--~~~~--~~--~--~---