I have a weird problem: Two identical functions, created using a
lambda from the same issuing identical SQL, return two different
answers. I'm embarrassed to say this, but it looks stochastic. I'm
running 0.4.2p3 with Python 2.5.2 and Ipython 0.8.1.

First, the guided tour. I'm using a lambda function to make new,
single-argument versions of a multi-argument function:

def _parse_fun(fun, fun_args=None):
    return lambda x: fun.__call__(x,fun_args)

Now I have another function that does some filtering and counting:

def n_classresps(unit,class_name):
    return query(ClassResponse).filter_by(unit=unit)\
                .filter_by(class_name=class_name).count()

And I use _parse_fun to set the value of the class_name argument:

yf = _parse_fun(n_classresps,'noise')

The problem comes when I make multiple instances:

foo = _parse_fun(n_classresps,'noise')

Now calling yf and foo returns different results: yf(qunits[0])
returns 0, while foo(qunits[0]) returns 3.

I've included a model below that reproduces my problem. The server is
a test server that only I'm using, so the database isn't changing. I
have this saved to a file, and I run it in IPython 0.8.1 using the run
command. After running, if I define

foo = _parse_fun(n_classresps,'zf song')

And foo(qunits[0]) gives me 3. Then I define

bar = _parse_fun(n_classresps,'zf song')

Now bar(qunits[0]) gives me 0. See where this is going?

The version in my full app reliably gives me the wrong answer, despite
issuing the right SQL. I've set engine.echo=True and enabled query
logging on the MySQL server, and the SQL is all fine. Running the SQL
with engine.execute gives the right answer, as does running the SQL
from a command-line tool.

Any ideas as to what could be causing this? I am at a complete loss.

Thanks,

Channing

--------------- Code follows -----------------

from sqlalchemy import MetaData, Table, Column, ForeignKey,
create_engine, Integer, String, select
from sqlalchemy.orm import mapper, relation, ColumnProperty,
scoped_session, sessionmaker
from sqlalchemy.databases.mysql import MSEnum

'''
Set up engine
'''
engine = create_engine('mysql://
channing:fi...@database.fet.berkeley.edu:3306/physiology')
Session = scoped_session(sessionmaker(autoflush=True,
transactional=True,
                                      bind=engine))
metadata = MetaData(engine)
query = Session.query

def _parse_fun(fun,fun_args=None):
    return lambda x: fun.__call__(x,fun_args)

def n_classresps(unit,class_name):
    return query(ClassResponse)\
                .filter_by(unit=unit)\
                .filter_by(class_name=class_name)\
                .count()

class Presentation(object):
    pass

class Response(object):
    pass

class Unit(object):
    pass

class ClassPresentation(Presentation):
    pass

class ClassResponse(Response):
    pass

presentations = Table('presentations', metadata,
                      Column('presentation_id', Integer,
                             primary_key=True, nullable=False),
                      Column('block_id', Integer, nullable=False),
                      Column('type', MSEnum
('single','repeated','class'),
                             nullable=False)
                      )

responses = Table('responses', metadata,
                  Column('response_id', Integer,
                         primary_key=True, nullable=False),
                  Column('unit_id', Integer,
                         ForeignKey('units.unit_id'),
                         nullable=False),
                  Column(u'presentation_id', Integer,
                         ForeignKey('presentations.presentation_id'),
                         nullable=False)
                  )

class_presentations = Table('class_presentations', metadata,
                            Column('presentation_id', Integer,
                                   ForeignKey
('presentations.presentation_id'),
                                   primary_key=True, nullable=False),
                            Column('class_name', String,
nullable=False)
                            )

units = Table('units', metadata,
              Column('unit_id', Integer, primary_key=True,
                     nullable=False),
              Column('recsite_id', Integer, nullable=False),
              Column('type', MSEnum('extracellular','intracellular'),
                     nullable=False)
              )

mapper(Presentation,presentations,
       polymorphic_on=presentations.c.type,
       polymorphic_identity='presentation')

rmapper = mapper(Response,responses.join(presentations),
                 polymorphic_on=presentations.c.type,
                 polymorphic_identity='response',
                 properties={'unit':relation(Unit)})

mapper(Unit,units)

mapper(ClassPresentation,class_presentations,
       inherits=Presentation,
       polymorphic_identity='class')

mapper(ClassResponse, inherits=rmapper,
       polymorphic_identity='class',
       properties={'class_name':ColumnProperty(select
([class_presentations.c.class_name],
 
responses.c.presentation_id==class_presentations.c.presentation_id)\
                                                      .label
('class_name'))})

''' The actual code that fails'''
qunits = query(Unit)
yf = _parse_fun(n_classresps,'zf_song')
a = yf(qunits[0])
#foo = _parse_fun(n_classresps,'zf_song')
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to