Dnia 2009-07-28, wto o godzinie 11:06 -0400, Michael Bayer pisze:

> A few things here.  First is, I'm not observing the extension not getting
> inherited.  Task().result = 3 raises the error, DeliveryTask().result = 3
> does not, and the value is assigned to 3.  This is with 0.5.5 as well as
> trunk.

[...]

>  So the sub column_property() needs to
> reference the original Column:

Hm, I fixed it to reference the parent's column, but still:

=======================================================================
fi...@cacko:~$ cat sqlawtf.py 
# Fails with Python-2.5.4 and SQLAlchemy-0.5.5
# There is happening something very strange, which causes 
# DeliveryTask.result not to cover Task.result even though DeliveryTask 
# is a child of Task.

import sqlalchemy
import sqlalchemy.ext.declarative

class TefDeclarativeMeta(sqlalchemy.ext.declarative.DeclarativeMeta):
    def __init__(cls, classname, bases, dict_):
        if '_decl_class_registry' in cls.__dict__:
            return type.__init__(cls, classname, bases, dict_)
        
        base = bases[0]
            
        cls.__tablename__ = cls.__name__

        if 'Id' not in dict_.keys():
            cls.Id = sqlalchemy.Column(sqlalchemy.types.Integer,
sqlalchemy.ForeignKey(base.Id), primary_key=True)
        
                
        if hasattr(base, 'Id'):
            cls.__mapper_args__ = {'inherit_condition': cls.Id ==
base.Id, 'polymorphic_identity': cls.__name__}
        
        sqlalchemy.ext.declarative._as_declarative(cls, classname,
dict_)
        
        return type.__init__(cls, classname, bases, dict_)

Base =
sqlalchemy.ext.declarative.declarative_base(metaclass=TefDeclarativeMeta, 
mapper=sqlalchemy.orm.mapper)

class TefEx(object):
    def __init__(self, enumDict):
        self.enumDict = enumDict

    def set(self, state, value, oldvalue, initiator):
        if value not in self.enumDict.keys():
            raise ValueError("value %s not in %s" % (value,
self.enumDict))
        return value

class Task(Base):
    Id = sqlalchemy.Column( sqlalchemy.types.Integer, primary_key=True,
autoincrement=True)
    objectType = sqlalchemy.Column( sqlalchemy.types.String(128),
nullable=False)
    __mapper_args__ = {'polymorphic_on': objectType}

    result =
sqlalchemy.orm.column_property(sqlalchemy.Column(sqlalchemy.types.Integer), 
extension = TefEx({0: 'Success', 1: 'Failure'}))


class DeliveryTask(Task):
    result = sqlalchemy.orm.column_property(Task.result, extension =
TefEx({0: 'Delivered', 1: 'Rejected', 2: 'Redirected', 3: 'Recipient
dead'}))

task = DeliveryTask()

task.result = 3
fi...@cacko:~$ python sqlawtf.py 
Traceback (most recent call last):
  File "sqlawtf.py", line 51, in <module>
    task.result = 3
  File
"/home/filip/tefnet/teferp/workspace/tefobjects/lib/python2.5/site-packages/SQLAlchemy-0.5.5-py2.5.egg/sqlalchemy/orm/attributes.py",
 line 150, in __set__
    self.impl.set(instance_state(instance), instance_dict(instance),
value, None)
  File
"/home/filip/tefnet/teferp/workspace/tefobjects/lib/python2.5/site-packages/SQLAlchemy-0.5.5-py2.5.egg/sqlalchemy/orm/attributes.py",
 line 451, in set
    value = self.fire_replace_event(state, dict_, value, old, initiator)
  File
"/home/filip/tefnet/teferp/workspace/tefobjects/lib/python2.5/site-packages/SQLAlchemy-0.5.5-py2.5.egg/sqlalchemy/orm/attributes.py",
 line 456, in fire_replace_event
    value = ext.set(state, value, previous, initiator or self)
  File "sqlawtf.py", line 35, in set
    raise ValueError("value %s not in %s" % (value, self.enumDict))
ValueError: value 3 not in {0: 'Success', 1: 'Failure'}
fi...@cacko:~$
=======================================================================
(file available at http://filip.math.uni.lodz.pl/sqlawtf.py)?

It is weird that this code works on your machine and doesn't on any of f
my setups:
* ubuntu 9.04 with Python 2.5.4 (r254:67916, Apr  4 2009, 17:55:16) and 
  SQLAlchemy-0.5.5 at Pentium M 1.3GHz
* ubuntu 9.04 with Python 2.6.2 (release26-maint, Apr 19 2009, 
  01:56:41) and SQLAlchemy-0.5.4p2 at Pentium M 1.3GHz
* ubuntu 9.04 with Python 2.6.2 (release26-maint, Apr 19 2009, 
  01:56:41) and SQLAlchemy-0.5.5 at Pentium M 1.3GHz
* gentoo with Python 2.5.4 (r254:67916, Apr 4 2009, 17:55:16) and 
  SQLAlchemy-0.5.5 at Intel Atom 330 1.6GHz
* gentoo with Python 2.5.2 (r252:60911, Mar 21 2009, 02:12:24) and
  SQLAlchemy-0.5.5 at 4x Intel Xeon E5335 2.00GHz 

Funny things happened while developing the project itself - sometimes
inheritance would work properly, and sometimes not (even in two
consecutive executions). I observed that slowing down the execution
increased failure rate (for example with python -m trace -t code.py
&>code.log).

For example:

fi...@cacko:~/tefnet/teferp/workspace/tefobjects/src/tefobjectsTests$
nosetests EnumProperty_test.py
....F.E.
======================================================================
ERROR: tefobjectsTests.EnumProperty_test.EnumOk1_test
----------------------------------------------------------------------
Traceback (most recent call last):
  File 
"/home/filip/tefnet/teferp/workspace/tefobjects/lib/python2.5/site-packages/nose-0.11.1-py2.5.egg/nose/case.py",
 line 183, in runTest
    self.test(*self.arg)
  File 
"/home/filip/tefnet/teferp/workspace/tefobjects/src/tefobjectsTests/EnumProperty_test.py",
 line 59, in EnumOk1_test
    b.attr=i
  File 
"/home/filip/tefnet/teferp/workspace/tefobjects/lib/python2.5/site-packages/SQLAlchemy-0.5.5-py2.5.egg/sqlalchemy/orm/attributes.py",
 line 150, in __set__
    self.impl.set(instance_state(instance), instance_dict(instance), value, 
None)
  File 
"/home/filip/tefnet/teferp/workspace/tefobjects/lib/python2.5/site-packages/SQLAlchemy-0.5.5-py2.5.egg/sqlalchemy/orm/attributes.py",
 line 451, in set
    value = self.fire_replace_event(state, dict_, value, old, initiator)
  File 
"/home/filip/tefnet/teferp/workspace/tefobjects/lib/python2.5/site-packages/SQLAlchemy-0.5.5-py2.5.egg/sqlalchemy/orm/attributes.py",
 line 456, in fire_replace_event
    value = ext.set(state, value, previous, initiator or self)
  File 
"/home/filip/tefnet/teferp/workspace/tefobjects/src/tefobjects/columnTypes/EnumType.py",
 line 62, in set
    raise EnumError(self, value)
EnumError: illegal value 3 for A.attr - EnumType({0: 'zero', 1: 'one', 2: 
'two'})

======================================================================
FAIL: tefobjectsTests.EnumProperty_test.EnumError1_test
----------------------------------------------------------------------
Traceback (most recent call last):
  File 
"/home/filip/tefnet/teferp/workspace/tefobjects/lib/python2.5/site-packages/nose-0.11.1-py2.5.egg/nose/case.py",
 line 183, in runTest
    self.test(*self.arg)
  File 
"/home/filip/tefnet/teferp/workspace/tefobjects/lib/python2.5/site-packages/nose-0.11.1-py2.5.egg/nose/tools.py",
 line 87, in newfunc
    raise AssertionError(message)
AssertionError: EnumError1_test() did not raise EnumError

----------------------------------------------------------------------
Ran 8 tests in 0.095s

FAILED (errors=1, failures=1)
fi...@cacko:~/tefnet/teferp/workspace/tefobjects/src/tefobjectsTests$

And another run:

fi...@cacko:~/tefnet/teferp/workspace/tefobjects/src/tefobjectsTests$ nosetests 
EnumProperty_test.py
........
----------------------------------------------------------------------
Ran 8 tests in 0.047s

OK
fi...@cacko:~/tefnet/teferp/workspace/tefobjects/src/tefobjectsTests$ 



Two consecutive runs - first fails, second passes. It's stateless -
there is nothing written to any database.

I'd rather avoid having the dict in the class directly not to have the
namespace polluted (there will be much more attributes).

bye,
Filip Zyzniewski
Tefnet



--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to