[sqlalchemy] How to do aggregates with mapped entity objects?

2007-02-27 Thread Pradeep

I have a expenses table with a amount field. I have mapped that table
to a Expense entity object.
How do I sum up all the amounts using my entity object.?


--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Spatial data (PostGIS/OGC) with SqlAlchemy

2007-02-27 Thread Allen Bierbaum

I just wanted to give an update.  I have found a solution that works
ok for now but I had to hack a bit.  I ended up having to use
psycopg2's ability to override how python classes are converted
to/from a database.  psycopg2 seems to have more complete support for
this then SA, so it let me convert to an exact string representation
for my type (ie. GeomFromText('POINT(1 1)') ).  I combined this with
the GeoTypes library to represent geometry types and to read them back
from the OGC binary format.

The relevant code looks like this:

import sqlalchemy as sa
import psycopg2.extensions
import logging
pe = psycopg2.extensions

from GeoTypes import (OGGeoTypeFactory, WKBParser,
 OGGeometry, OGPoint, OGPolygon, OGLineString)

class PostGisWKBFactory(object):
   def __init__(self):
  pass

   def __call__(self, s=None):
  factory = OGGeoTypeFactory()
  parser = WKBParser(factory)
  parser.parseGeometry(s)
  return factory.getGeometry()


class GeometryType(sa.types.TypeEngine):
   def __init__(self, SRID, typeName, dimension):
  super(GeometryType, self).__init__()
  self.mSrid = SRID
  self.mType = typeName.upper()
  self.mDim  = dimension
  self.bfact = PostGisWKBFactory()

   def __repr__(self):
  return %s:%s-%s(%s) % (self.__class__.__name__, self.mType,
self.mDim, self.mSrid)

   def get_col_spec(self):
  return GEOMETRY

   def convert_bind_param(self, value, engine):
  # Could be used to make the type _conform_
  #return pe.AsIs(str(value))
  return value

   def convert_result_value(self, value, engine):
  geom_obj = self.bfact(binascii.a2b_hex(value))
  geom_obj._srid = self.mSrid   # set directly
  return geom_obj

class GeometryPOINT(GeometryType):
   def __init__(self, srid):
  super(GeometryPOINT,self).__init__(srid, POINT, 2)

class GeometryLINESTRING(GeometryType):
   def __init__(self, srid):
  super(GeometryPOINT,self).__init__(srid, LINESTRING, 2)


Then I added the following method to the GeoTypes.Geometry class to
allow it to represent itself to psycopg2 correctly.

# Interface to allow psycopg2 to convert to database automatically
def getquoted(self):
return self.__str__()

def __conform__(self, proto):
# Return ourselves since we have a getquoted method
return self

I still don't see a way to handle this directly with SA, so if anyone
can tell me a way to let SA know exactly how I want the object's value
to appear in the generated SQL statement please let me know so I can
refine my code.

Thanks,
Allen


On 2/25/07, Allen Bierbaum [EMAIL PROTECTED] wrote:
 [snip]
   When I use this with my table and datamapper code, it looks like
  everything is working fine but the generated SQL insert statement
  fails with a exception:
 
  sqlalchemy.exceptions.SQLError: (ProgrammingError) parse error -
  invalid geometry
'INSERT INTO gis_entity (id, name, pos) VALUES (%(mId)s, %(mName)s,
  %(mPos)s)' {'mName': 'New entity', 'mId': 1L, 'mPos':
  GeomFromText('POINT(100 100)',-1)}
 
  I know from using sql directly in pgadmin3 that this line works correctly:
 
  insert into gis_entity (id, name, pos) values (2, 'New entity',
  GeomFromText('POINT(100 100)', -1));
 
  Does anyone see how this varies from the sql statement issued by SA?

 By looking at the postgres log I figured out what was causing the
 error, but I still don't know how to fix it.

 The problem is that SA considers GeomFromText('POINT(100 100)', -1)
 to be a string so it puts it in single quotes when creating the SQL
 command to execute. This causes problems because them postgres doesn't
 know it could be calling a method instead.  I have tried returning an
 sqlalchemy.func object but this doesn't work either.

 Any ideas?

 -Allen


--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] How do I get columns in sqlalchemy group by function

2007-02-27 Thread vinjvinj

I have the following columns in some of my select columns:

group_by_column = sqlalchemy.func.sum(column1)

How do I get column1 from the group_by_column object (In other words
is there any way to find out what columns the function is going to be
applied to?). I did a dir(group_by_column) and saw that it had a field
called columns, but that did not have the values I was looking for.

Thanks,

VJ


--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: How to do aggregates with mapped entity objects?

2007-02-27 Thread Jonathan Ellis

You don't, it doesn't work that way.

You can map the aggregate as a (SA) property of another class, or make
it a (Python) property/function of the Expense class.  Either way
you'll have to create a select object, either for the mapping or a
manual query.

On 2/27/07, Pradeep [EMAIL PROTECTED] wrote:

 I have a expenses table with a amount field. I have mapped that table
 to a Expense entity object.
 How do I sum up all the amounts using my entity object.?


 


--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Spatial data (PostGIS/OGC) with SqlAlchemy

2007-02-27 Thread Michael Bayer

these are all SA bugs/possible inaccuracies in API usage.  you should  
be able to execute the function as I described below, you should be  
able to put the function into an INSERT statement as well.  Ill test  
these features later today.

On Feb 25, 2007, at 3:43 PM, Allen Bierbaum wrote:


 I tried your idea but it doesn't seem to be valid code.  Here is the
 code I tried:

print Trying with a transaction.
conn = db.connect()
trans = conn.begin()
conn.execute(sa.func.AddGeometryColumn 
 ('','gis_entity','fpos',-1,'LINESTRING',2))
trans.commit()
conn.close()

 and here is the exception I get on the execute line:

 Try with a transaction.
 INFO:sqlalchemy.engine.base.Engine.0x..d0:BEGIN
 Traceback (most recent call last):
   File gis_type_test.py, line 73, in ?
 conn.execute(sa.func.AddGeometryColumn 
 ('','gis_entity','fpos',-1,'LINESTRING',2,
 engine=db))
   File /usr/lib/python2.4/site-packages/sqlalchemy/engine/base.py,
 line 258, in execute
 return Connection.executors[type(object).__mro__[-2]](self,
 object, *multiparams, **params)
 KeyError: class 'sqlalchemy.sql._CompareMixin'

 I am now running into a new problem as well though.  I can use my
 previous hack to insert the column but I can't add data to it because
 I have been unable to call GeomFromText(..) on the insert.

 I tried to get this working by defining my own type:
 class GeometryType(sa.types.TypeEngine):

def __init__(self, SRID, typeName, dimension):
   super(GeometryType, self).__init__()
   self.mSrid = SRID
   self.mType = typeName.upper()
   self.mDim  = dimension

def __repr__(self):
   return %s:%s-%s(%s) % (self.__class__.__name__, self.mType,
 self.mDim, self.mSrid)

def get_col_spec(self):
   return GEOMETRY

def convert_bind_param(self, value, engine):
   return 'GeomFromText(\'%s\',%s)'%(value, self.mSrid)

def convert_result_value(self, value, engine):
   # Not used yet
   return value

 When I use this with my table and datamapper code, it looks like
 everything is working fine but the generated SQL insert statement
 fails with a exception:

 sqlalchemy.exceptions.SQLError: (ProgrammingError) parse error -
 invalid geometry
   'INSERT INTO gis_entity (id, name, pos) VALUES (%(mId)s, %(mName)s,
 %(mPos)s)' {'mName': 'New entity', 'mId': 1L, 'mPos':
 GeomFromText('POINT(100 100)',-1)}

 I know from using sql directly in pgadmin3 that this line works  
 correctly:

 insert into gis_entity (id, name, pos) values (2, 'New entity',
 GeomFromText('POINT(100 100)', -1));

 Does anyone see how this varies from the sql statement issued by SA?
 I have stared at it for 20 minutes and I don't see a difference.
 Is there any way to see the raw SQL statement sent by SA to postgres?
 I have turned up the debug output level to full but I still only can
 see the format string and parameters used for making the sql
 statement:

 INFO:sqlalchemy.engine.base.Engine.0x..50:INSERT INTO gis_entity (id,
 name, pos) VALUES (%(mId)s, %(mName)s, %(mPos)s)
 INFO:sqlalchemy.engine.base.Engine.0x..50:{'mName': 'New entity',
 'mId': 1L, 'mPos': GeomFromText('POINT(100 100)',-1)}

 Does anyone see what I am doing wrong here?

 Once I get this working, then I have to figure out how to get the data
 back out from postgis. What I want to end up with here is an SQL
 statement like this:

 select id, name, AsText(pos) as pos from gis_entity;

 Note that pos is retrieved through a server side function ('AsText')
 that unpacks the binary representation from the database into a string
 representation.  Is there any way to do this with SA so the system
 will always create queries in this form whenever it tries to retrieve
 the value of pos?

 I don't know if this makes a solution easier, but I am using mappers
 for all my tables.  What I would really like to have is a mapper that
 would just automatically know to wrap all references to pos in
 INSERT calls with a call to the server-side function 'GeomFromText'
 and correspondingly wrap all references to pos in SELECT calls with
 a call to the server-side function 'AsText'.  Is it possible to do
 this at the mapper level?  If it is, then that could greatly simplify
 everything I am trying to do here.

 Thanks for you help.

 -Allen

 On 2/25/07, Michael Bayer [EMAIL PROTECTED] wrote:

   if the function youre calling needs a transaction commit, why dont
 you call an explicit transaction ?

 conn = engine.connect()
 trans = conn.begin()
 conn.execute(func.AddGeometryColumn
 ('','gis_entity','fpos',-1,'LINESTRING',2))
 trans.commit()


 On Feb 25, 2007, at 11:02 AM, Allen Bierbaum wrote:


 I have been pursuing this further on my own and one of the issues I
 have run into is how to cleanly add a geometry column to a database.
 The posting referenced in the first e-mail [2] talks about doing  
 this
 directly with psycopg2 cursor because the poster could not get it
 working with SA.  I gave it another try to see if I could get 

[sqlalchemy] Auto-joins via FK

2007-02-27 Thread Rick Morrison
Shouldn't SA be able to figure out the following joins without needing the
explicit join params?

I've got to be missing something dumb.

from sqlalchemy import *

metadata = BoundMetaData('sqlite:///:memory:')

ent = Table('entity', metadata,
Column('id',  INT,  Sequence('entity_id'), primary_key=True,
nullable=False),
Column('nm',  VARCHAR(12), nullable=False)
)

loc = Table('location', metadata,
  Column('id',  INT, Sequence('location_id'),
primary_key=True, nullable=False),
  Column('nm',  VARCHAR(50))
  )

el = Table('el_rel', metadata,
  Column('typ', VARCHAR(12), nullable=False),
  Column('ident',   INT, ForeignKey('entity.id'),
nullable=False),
  Column('idloc',   INT, ForeignKey('location.id'),
nullable=False)
  )

metadata.create_all()

ent.insert().execute({'id':1, 'nm':'Eone'},  {'id':2, 'nm':'Etwo'},
{'id':3, 'nm':'Ethree'})
loc.insert().execute({'id':1, 'nm':'Lone'}, {'id':2, 'nm':'Ltwo'}, {'id':3,
'nm':'Lthree'})
el.insert().execute({'typ':'TEST1', 'ident':1, 'idloc':1}, {'typ':'TEST2',
'ident':2, 'idloc':2})

testcases = [('2-way -ent', [ent.c.nm], None),
 ('2-way -loc', [loc.c.nm], None),
 ('3-way -ent+loc', [ent.c.nm, loc.c.nm], None),
 ('3-way, explicit join', [ent.c.nm, loc.c.nm],
  el.join(ent, ent.c.id==el.c.ident).join(loc,
loc.c.id==el.c.idloc))
 ]

for test_name, test_cols, test_from in testcases:
print
print test_name
q = select(test_cols, el.c.typ == 'TEST1')
if test_from:
q.append_from(test_from)
print str(q)
print q.execute().fetchall()



Thx,
Rick

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Spatial data (PostGIS/OGC) with SqlAlchemy

2007-02-27 Thread Michael Bayer

OK, for the function execution, the syntax that works with release  
0.3.5 is:

conn = db.connect()
trans = conn.begin()
conn.execute(func.AddGeometryColumn 
('','gis_entity','fpos',-1,'LINESTRING',2).select())
trans.commit()
conn.close()

notice it just adds a select().in changeset 2364, you dont need  
the select.

inserts with functions are done like this:

# without a connection
table.insert().execute(somecolumn = func.GeometryFunction(arg1, arg2,  
arg3...))

# with a connection
conn.execute(table.insert(), somecolumn = func.GeometryFunction(arg1,  
arg2, arg3...))

On Feb 27, 2007, at 10:42 AM, Michael Bayer wrote:


 these are all SA bugs/possible inaccuracies in API usage.  you should
 be able to execute the function as I described below, you should be
 able to put the function into an INSERT statement as well.  Ill test
 these features later today.

 On Feb 25, 2007, at 3:43 PM, Allen Bierbaum wrote:


 I tried your idea but it doesn't seem to be valid code.  Here is the
 code I tried:

print Trying with a transaction.
conn = db.connect()
trans = conn.begin()
conn.execute(sa.func.AddGeometryColumn
 ('','gis_entity','fpos',-1,'LINESTRING',2))
trans.commit()
conn.close()

 and here is the exception I get on the execute line:

 Try with a transaction.
 INFO:sqlalchemy.engine.base.Engine.0x..d0:BEGIN
 Traceback (most recent call last):
   File gis_type_test.py, line 73, in ?
 conn.execute(sa.func.AddGeometryColumn
 ('','gis_entity','fpos',-1,'LINESTRING',2,
 engine=db))
   File /usr/lib/python2.4/site-packages/sqlalchemy/engine/base.py,
 line 258, in execute
 return Connection.executors[type(object).__mro__[-2]](self,
 object, *multiparams, **params)
 KeyError: class 'sqlalchemy.sql._CompareMixin'

 I am now running into a new problem as well though.  I can use my
 previous hack to insert the column but I can't add data to it because
 I have been unable to call GeomFromText(..) on the insert.

 I tried to get this working by defining my own type:
 class GeometryType(sa.types.TypeEngine):

def __init__(self, SRID, typeName, dimension):
   super(GeometryType, self).__init__()
   self.mSrid = SRID
   self.mType = typeName.upper()
   self.mDim  = dimension

def __repr__(self):
   return %s:%s-%s(%s) % (self.__class__.__name__, self.mType,
 self.mDim, self.mSrid)

def get_col_spec(self):
   return GEOMETRY

def convert_bind_param(self, value, engine):
   return 'GeomFromText(\'%s\',%s)'%(value, self.mSrid)

def convert_result_value(self, value, engine):
   # Not used yet
   return value

 When I use this with my table and datamapper code, it looks like
 everything is working fine but the generated SQL insert statement
 fails with a exception:

 sqlalchemy.exceptions.SQLError: (ProgrammingError) parse error -
 invalid geometry
   'INSERT INTO gis_entity (id, name, pos) VALUES (%(mId)s, %(mName)s,
 %(mPos)s)' {'mName': 'New entity', 'mId': 1L, 'mPos':
 GeomFromText('POINT(100 100)',-1)}

 I know from using sql directly in pgadmin3 that this line works
 correctly:

 insert into gis_entity (id, name, pos) values (2, 'New entity',
 GeomFromText('POINT(100 100)', -1));

 Does anyone see how this varies from the sql statement issued by SA?
 I have stared at it for 20 minutes and I don't see a difference.
 Is there any way to see the raw SQL statement sent by SA to postgres?
 I have turned up the debug output level to full but I still only can
 see the format string and parameters used for making the sql
 statement:

 INFO:sqlalchemy.engine.base.Engine.0x..50:INSERT INTO gis_entity (id,
 name, pos) VALUES (%(mId)s, %(mName)s, %(mPos)s)
 INFO:sqlalchemy.engine.base.Engine.0x..50:{'mName': 'New entity',
 'mId': 1L, 'mPos': GeomFromText('POINT(100 100)',-1)}

 Does anyone see what I am doing wrong here?

 Once I get this working, then I have to figure out how to get the  
 data
 back out from postgis. What I want to end up with here is an SQL
 statement like this:

 select id, name, AsText(pos) as pos from gis_entity;

 Note that pos is retrieved through a server side function ('AsText')
 that unpacks the binary representation from the database into a  
 string
 representation.  Is there any way to do this with SA so the system
 will always create queries in this form whenever it tries to retrieve
 the value of pos?

 I don't know if this makes a solution easier, but I am using mappers
 for all my tables.  What I would really like to have is a mapper that
 would just automatically know to wrap all references to pos in
 INSERT calls with a call to the server-side function 'GeomFromText'
 and correspondingly wrap all references to pos in SELECT calls with
 a call to the server-side function 'AsText'.  Is it possible to do
 this at the mapper level?  If it is, then that could greatly simplify
 everything I am trying to do here.

 Thanks for you help.

 -Allen

 On 2/25/07, Michael Bayer [EMAIL PROTECTED] wrote:

   if the 

[sqlalchemy] Re: Auto-joins via FK

2007-02-27 Thread Jonathan Ellis

On 2/27/07, Rick Morrison [EMAIL PROTECTED] wrote:
 Shouldn't SA be able to figure out the following joins without needing the
 explicit join params?

no, SA never tries to guess how you want to join things because then
you'd have to add a way to override it when it guesses wrong and it's
simpler to just make things explicit in the first place.

the join function will automatically do FK-based where conditions,
that's probably what you want.

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Auto-joins via FK

2007-02-27 Thread Michael Bayer
the join() function, given two tables, will make a foreign key join  
condition by default if you dont specify the onclause.  but if you  
arent using a join function somewhere, then nothing else is going  
to generate any clauses for you.

On Feb 27, 2007, at 10:50 AM, Rick Morrison wrote:

 Shouldn't SA be able to figure out the following joins without  
 needing the explicit join params?

 I've got to be missing something dumb.

 from sqlalchemy import *

 metadata = BoundMetaData('sqlite:///:memory:')

 ent = Table('entity', metadata,
 Column('id',  INT,  Sequence('entity_id'),  
 primary_key=True, nullable=False),
 Column('nm',  VARCHAR(12), nullable=False)
 )

 loc = Table('location', metadata,
   Column('id',  INT, Sequence('location_id'),  
 primary_key=True, nullable=False),
   Column('nm',  VARCHAR(50))
   )

 el = Table('el_rel', metadata,
   Column('typ', VARCHAR(12), nullable=False),
   Column('ident',   INT, ForeignKey(' entity.id'),   
 nullable=False),
   Column('idloc',   INT, ForeignKey('location.id'),  
 nullable=False)
   )

 metadata.create_all()

 ent.insert ().execute({'id':1, 'nm':'Eone'},  {'id':2,  
 'nm':'Etwo'},  {'id':3, 'nm':'Ethree'})
 loc.insert().execute({'id':1, 'nm':'Lone'}, {'id':2, 'nm':'Ltwo'},  
 {'id':3, 'nm':'Lthree'})
 el.insert().execute({'typ':'TEST1', 'ident':1, 'idloc':1},  
 {'typ':'TEST2', 'ident':2, 'idloc':2})

 testcases = [('2-way -ent', [ent.c.nm ], None),
  ('2-way -loc', [loc.c.nm], None),
  ('3-way -ent+loc', [ent.c.nm, loc.c.nm], None),
  ('3-way, explicit join', [ent.c.nm, loc.c.nm],
   el.join(ent, ent.c.id==el.c.ident).join(loc,  
 loc.c.id==el.c.idloc))
  ]

 for test_name, test_cols, test_from in testcases:
 print
 print test_name
 q = select(test_cols, el.c.typ == 'TEST1')
 if test_from:
 q.append_from(test_from)
 print str(q)
 print q.execute().fetchall()



 Thx,
 Rick

 


--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: contains_eager is somehow not loading all the instances.

2007-02-27 Thread Michael Bayer
if you run it with full blown logging on, i.e.:

import logging
logging.basicConfig()
logging.getLogger('sqlalchemy.engine').setLevel(logging.DEBUG)
logging.getLogger('sqlalchemy.orm').setLevel(logging.DEBUG)


the issue can be detected when you look at the mapper creating  
instance keys for T (although this is clearly not a novice issue):

DEBUG:sqlalchemy.orm.mapper.Mapper:(T|ts) _instance(): identity key  
(class '__main__.T', (1,), None) not in session[]
DEBUG:sqlalchemy.orm.mapper.Mapper:(T|ts) _instance(): identity key  
(class '__main__.T', (None,), None) not in session[]
DEBUG:sqlalchemy.orm.mapper.Mapper:(T|ts) _instance(): identity key  
(class '__main__.T', (3,), None) not in session[]
DEBUG:sqlalchemy.orm.mapper.Mapper:(T|ts) _instance(): identity key  
(class '__main__.T', (None,), None) not in session[]
DEBUG:sqlalchemy.orm.mapper.Mapper:(T|ts) _instance(): identity key  
(class '__main__.T', (5,), None) not in session[]

so its not getting an identity key for every other row, which  
indicates its looking at the wrong column in the result set.   (on  
each of those Nones, its going to skip that entity) looking at the  
query:

SELECT ts.id, ts.dat, other.ts_id, other.other_dat
FROM ts LEFT OUTER JOIN other ON ts.id = other.ts_id

we can see that other has a column called ts_id, which looks  
exactly like the label that would be made for id in table ts.  so  
thats whats happening here.   so throwing on a use_labels=True to  
the query (or changing the name of ts_id) produces the query:

SELECT ts.id AS ts_id, ts.dat AS ts_dat, other.ts_id AS other_ts_id,  
other.other_dat AS other_other_dat
FROM ts LEFT OUTER JOIN other ON ts.id = other.ts_id

that gives the correct results.

not sure what SA can really do here to make this kind of issue easier  
to catch, since the resultproxy itself is where its looking for col  
label, col name, , etc.  the generated labels are generally more  
accurate.  i tried playing around with ResultProxy to make it detect  
an ambiguity of this nature, but i think it might not be possible  
unless more flags/switches get passed from the statement to the  
result (which id rather not do since it further marginalizes straight  
textual queries), since if the select statement uses table/col labels  
for each column, there still could be conflicts which dont matter,  
such as the column names the normal eager loader generates:

'ts_id', 'ts_dat', 'other_4966_ts_id', 'other_4966_other_dat',

that result is from column ts_id attached to an Alias  
other_4966.  if we said dont allow any Column to be found twice in  
the row, then that breaks (since it will match other_4966_ts_id on  
its _label, ts_id on its name).



On Feb 27, 2007, at 12:09 PM, Dennis Muhlestein wrote:

 from sqlalchemy import *


 e=create_engine('sqlite://memory')
 ts=Table('ts',e,
   Column ( 'id',Integer,primary_key=True),
   Column ( 'dat',Integer,nullable=False))
 ts.create()

 to_oneornone=Table('other',e,
   Column ( 'ts_id', Integer,ForeignKey('ts.id'), primary_key=True,  
 nullable=False ),
   Column ( 'other_dat', Integer, nullable=False ) )
 to_oneornone.create()

 class T(object): pass
 T.mapper=mapper(T,ts)

 class To(object):pass
 To.mapper=mapper(To,to_oneornone,properties={'ts':relation 
 (T,backref=backref('other',uselist=False))})


 s=create_session()
 for x in range(10):
  t=T()
  t.dat=x
  s.save(t)

  if x % 2 == 0: # test every other T has an optional data
   o=To()
   o.other_dat=x
   t.other=o

  s.save(t)
  s.flush()

 s.clear()

 somedata=s.query(T).options(eagerload('other')).select()
 print 'Number results should be 10: ', len(somedata)

 s.clear()


 sel=select([ts,to_oneornone],
   from_obj=[ts.outerjoin(to_oneornone)])

 print Raw select also is 10:  , len(sel.execute().fetchall() )


 print Instances should also be 10: , len(s.query(T).options 
 (contains_eager('other')).instances(sel.execute()))


--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: contains_eager is somehow not loading all the instances.

2007-02-27 Thread Dennis

Thanks for taking a peek.

Interesting, it does indeed fix the issue to use labels.  Now I have
another issue though, I have a case statement in my select which I was
specifying like this:

select ( ['case when  yada yada yada end as something' ] ..

If use_labels = True, then the query breaks because the generated sql
has two as label parts two it.

if I delete the as something part, I think don't know
programatically what the label is though.  I need to know that because
I order by it.

Isn't there a way to find out a column label from a query?

-Dennis

On Feb 27, 12:47 pm, Michael Bayer [EMAIL PROTECTED] wrote:
 if you run it with full blown logging on, i.e.:

 import logging
 logging.basicConfig()
 logging.getLogger('sqlalchemy.engine').setLevel(logging.DEBUG)
 logging.getLogger('sqlalchemy.orm').setLevel(logging.DEBUG)

 the issue can be detected when you look at the mapper creating
 instance keys for T (although this is clearly not a novice issue):

 DEBUG:sqlalchemy.orm.mapper.Mapper:(T|ts) _instance(): identity key
 (class '__main__.T', (1,), None) not in session[]
 DEBUG:sqlalchemy.orm.mapper.Mapper:(T|ts) _instance(): identity key
 (class '__main__.T', (None,), None) not in session[]
 DEBUG:sqlalchemy.orm.mapper.Mapper:(T|ts) _instance(): identity key
 (class '__main__.T', (3,), None) not in session[]
 DEBUG:sqlalchemy.orm.mapper.Mapper:(T|ts) _instance(): identity key
 (class '__main__.T', (None,), None) not in session[]
 DEBUG:sqlalchemy.orm.mapper.Mapper:(T|ts) _instance(): identity key
 (class '__main__.T', (5,), None) not in session[]

 so its not getting an identity key for every other row, which
 indicates its looking at the wrong column in the result set.   (on
 each of those Nones, its going to skip that entity) looking at the
 query:

 SELECT ts.id, ts.dat, other.ts_id, other.other_dat
 FROM ts LEFT OUTER JOIN other ON ts.id = other.ts_id

 we can see that other has a column called ts_id, which looks
 exactly like the label that would be made for id in table ts.  so
 thats whats happening here.   so throwing on a use_labels=True to
 the query (or changing the name of ts_id) produces the query:

 SELECT ts.id AS ts_id, ts.dat AS ts_dat, other.ts_id AS other_ts_id,
 other.other_dat AS other_other_dat
 FROM ts LEFT OUTER JOIN other ON ts.id = other.ts_id

 that gives the correct results.

 not sure what SA can really do here to make this kind of issue easier
 to catch, since the resultproxy itself is where its looking for col
 label, col name, , etc.  the generated labels are generally more
 accurate.  i tried playing around with ResultProxy to make it detect
 an ambiguity of this nature, but i think it might not be possible
 unless more flags/switches get passed from the statement to the
 result (which id rather not do since it further marginalizes straight
 textual queries), since if the select statement uses table/col labels
 for each column, there still could be conflicts which dont matter,
 such as the column names the normal eager loader generates:

 'ts_id', 'ts_dat', 'other_4966_ts_id', 'other_4966_other_dat',

 that result is from column ts_id attached to an Alias
 other_4966.  if we said dont allow any Column to be found twice in
 the row, then that breaks (since it will match other_4966_ts_id on
 its _label, ts_id on its name).

 On Feb 27, 2007, at 12:09 PM, Dennis Muhlestein wrote:

  from sqlalchemy import *

  e=create_engine('sqlite://memory')
  ts=Table('ts',e,
 Column ( 'id',Integer,primary_key=True),
 Column ( 'dat',Integer,nullable=False))
  ts.create()

  to_oneornone=Table('other',e,
 Column ( 'ts_id', Integer,ForeignKey('ts.id'), primary_key=True,
  nullable=False ),
 Column ( 'other_dat', Integer, nullable=False ) )
  to_oneornone.create()

  class T(object): pass
  T.mapper=mapper(T,ts)

  class To(object):pass
  To.mapper=mapper(To,to_oneornone,properties={'ts':relation
  (T,backref=backref('other',uselist=False))})

  s=create_session()
  for x in range(10):
   t=T()
   t.dat=x
   s.save(t)

   if x % 2 == 0: # test every other T has an optional data
o=To()
o.other_dat=x
t.other=o

   s.save(t)
   s.flush()

  s.clear()

  somedata=s.query(T).options(eagerload('other')).select()
  print 'Number results should be 10: ', len(somedata)

  s.clear()

  sel=select([ts,to_oneornone],
 from_obj=[ts.outerjoin(to_oneornone)])

  print Raw select also is 10:  , len(sel.execute().fetchall() )

  print Instances should also be 10: , len(s.query(T).options
  (contains_eager('other')).instances(sel.execute()))


--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: contains_eager is somehow not loading all the instances.

2007-02-27 Thread Michael Bayer

the label is always tablename_columnname.   youd have to show me  
where you need that to be programmatic.

On Feb 27, 2007, at 2:29 PM, Dennis wrote:


 Thanks for taking a peek.

 Interesting, it does indeed fix the issue to use labels.  Now I have
 another issue though, I have a case statement in my select which I was
 specifying like this:

 select ( ['case when  yada yada yada end as something' ] ..

 If use_labels = True, then the query breaks because the generated sql
 has two as label parts two it.

 if I delete the as something part, I think don't know
 programatically what the label is though.  I need to know that because
 I order by it.

 Isn't there a way to find out a column label from a query?

 -Dennis

 On Feb 27, 12:47 pm, Michael Bayer [EMAIL PROTECTED] wrote:
 if you run it with full blown logging on, i.e.:

 import logging
 logging.basicConfig()
 logging.getLogger('sqlalchemy.engine').setLevel(logging.DEBUG)
 logging.getLogger('sqlalchemy.orm').setLevel(logging.DEBUG)

 the issue can be detected when you look at the mapper creating
 instance keys for T (although this is clearly not a novice issue):

 DEBUG:sqlalchemy.orm.mapper.Mapper:(T|ts) _instance(): identity key
 (class '__main__.T', (1,), None) not in session[]
 DEBUG:sqlalchemy.orm.mapper.Mapper:(T|ts) _instance(): identity key
 (class '__main__.T', (None,), None) not in session[]
 DEBUG:sqlalchemy.orm.mapper.Mapper:(T|ts) _instance(): identity key
 (class '__main__.T', (3,), None) not in session[]
 DEBUG:sqlalchemy.orm.mapper.Mapper:(T|ts) _instance(): identity key
 (class '__main__.T', (None,), None) not in session[]
 DEBUG:sqlalchemy.orm.mapper.Mapper:(T|ts) _instance(): identity key
 (class '__main__.T', (5,), None) not in session[]

 so its not getting an identity key for every other row, which
 indicates its looking at the wrong column in the result set.   (on
 each of those Nones, its going to skip that entity) looking at the
 query:

 SELECT ts.id, ts.dat, other.ts_id, other.other_dat
 FROM ts LEFT OUTER JOIN other ON ts.id = other.ts_id

 we can see that other has a column called ts_id, which looks
 exactly like the label that would be made for id in table ts.  so
 thats whats happening here.   so throwing on a use_labels=True to
 the query (or changing the name of ts_id) produces the query:

 SELECT ts.id AS ts_id, ts.dat AS ts_dat, other.ts_id AS other_ts_id,
 other.other_dat AS other_other_dat
 FROM ts LEFT OUTER JOIN other ON ts.id = other.ts_id

 that gives the correct results.

 not sure what SA can really do here to make this kind of issue easier
 to catch, since the resultproxy itself is where its looking for col
 label, col name, , etc.  the generated labels are generally more
 accurate.  i tried playing around with ResultProxy to make it detect
 an ambiguity of this nature, but i think it might not be possible
 unless more flags/switches get passed from the statement to the
 result (which id rather not do since it further marginalizes straight
 textual queries), since if the select statement uses table/col labels
 for each column, there still could be conflicts which dont matter,
 such as the column names the normal eager loader generates:

 'ts_id', 'ts_dat', 'other_4966_ts_id', 'other_4966_other_dat',

 that result is from column ts_id attached to an Alias
 other_4966.  if we said dont allow any Column to be found twice in
 the row, then that breaks (since it will match other_4966_ts_id on
 its _label, ts_id on its name).

 On Feb 27, 2007, at 12:09 PM, Dennis Muhlestein wrote:

 from sqlalchemy import *

 e=create_engine('sqlite://memory')
 ts=Table('ts',e,
Column ( 'id',Integer,primary_key=True),
Column ( 'dat',Integer,nullable=False))
 ts.create()

 to_oneornone=Table('other',e,
Column ( 'ts_id', Integer,ForeignKey('ts.id'), primary_key=True,
 nullable=False ),
Column ( 'other_dat', Integer, nullable=False ) )
 to_oneornone.create()

 class T(object): pass
 T.mapper=mapper(T,ts)

 class To(object):pass
 To.mapper=mapper(To,to_oneornone,properties={'ts':relation
 (T,backref=backref('other',uselist=False))})

 s=create_session()
 for x in range(10):
  t=T()
  t.dat=x
  s.save(t)

  if x % 2 == 0: # test every other T has an optional data
   o=To()
   o.other_dat=x
   t.other=o

  s.save(t)
  s.flush()

 s.clear()

 somedata=s.query(T).options(eagerload('other')).select()
 print 'Number results should be 10: ', len(somedata)

 s.clear()

 sel=select([ts,to_oneornone],
from_obj=[ts.outerjoin(to_oneornone)])

 print Raw select also is 10:  , len(sel.execute().fetchall() )

 print Instances should also be 10: , len(s.query(T).options
 (contains_eager('other')).instances(sel.execute()))


 


--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, 

[sqlalchemy] Print of returned object fails

2007-02-27 Thread Gloria

I am not able to print the object returned by sqlAlchemy in this
instance:

clients=Table('clients',metadata, autoload=True)
s = clients.select(clients.c.client_id==client_id)
#print str(s)
result = s.execute()
client = result.fetchone()
print client

The error:

Traceback (most recent call last):
  File db_interface/sqlAlchemyTest.py, line 61, in module
x=getClientData(1390)
  File db_interface/sqlAlchemyTest.py, line 46, in getClientData
print client
  File build/bdist.linux-i686/egg/sqlalchemy/engine/base.py, line
811, in __repr__
  File build/bdist.linux-i686/egg/sqlalchemy/engine/base.py, line
672, in _get_col
  File build/bdist.linux-i686/egg/sqlalchemy/databases/postgres.py,
line 81, in convert_result_value
IndexError: list index out of range

I'm using Postgresql 8.1.5 and Psycopg 1.99.13 (the latter is old, and
used intentionally).

Thank you,
~G~


--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: contains_eager is somehow not loading all the instances.

2007-02-27 Thread Dennis

Well, columnname isn't a simple column in the case of a case
statement... the label is turning out like this:

casewhenhas_testtrueandscoreisnullandgender1then1whenscoreisnullthen2elsescoreend

I haven't found a way to manually assign a label to a text clause yet,
but before I tried use_labels=True, I has appended as score to the
case clause and that worked.

On Feb 27, 2:44 pm, Michael Bayer [EMAIL PROTECTED] wrote:
 the label is always tablename_columnname.   youd have to show me
 where you need that to be programmatic.

 On Feb 27, 2007, at 2:29 PM, Dennis wrote:



  Thanks for taking a peek.

  Interesting, it does indeed fix the issue to use labels.  Now I have
  another issue though, I have a case statement in my select which I was
  specifying like this:

  select ( ['case when  yada yada yada end as something' ] ..

  If use_labels = True, then the query breaks because the generated sql
  has two as label parts two it.

  if I delete the as something part, I think don't know
  programatically what the label is though.  I need to know that because
  I order by it.

  Isn't there a way to find out a column label from a query?

  -Dennis

  On Feb 27, 12:47 pm, Michael Bayer [EMAIL PROTECTED] wrote:
  if you run it with full blown logging on, i.e.:

  import logging
  logging.basicConfig()
  logging.getLogger('sqlalchemy.engine').setLevel(logging.DEBUG)
  logging.getLogger('sqlalchemy.orm').setLevel(logging.DEBUG)

  the issue can be detected when you look at the mapper creating
  instance keys for T (although this is clearly not a novice issue):

  DEBUG:sqlalchemy.orm.mapper.Mapper:(T|ts) _instance(): identity key
  (class '__main__.T', (1,), None) not in session[]
  DEBUG:sqlalchemy.orm.mapper.Mapper:(T|ts) _instance(): identity key
  (class '__main__.T', (None,), None) not in session[]
  DEBUG:sqlalchemy.orm.mapper.Mapper:(T|ts) _instance(): identity key
  (class '__main__.T', (3,), None) not in session[]
  DEBUG:sqlalchemy.orm.mapper.Mapper:(T|ts) _instance(): identity key
  (class '__main__.T', (None,), None) not in session[]
  DEBUG:sqlalchemy.orm.mapper.Mapper:(T|ts) _instance(): identity key
  (class '__main__.T', (5,), None) not in session[]

  so its not getting an identity key for every other row, which
  indicates its looking at the wrong column in the result set.   (on
  each of those Nones, its going to skip that entity) looking at the
  query:

  SELECT ts.id, ts.dat, other.ts_id, other.other_dat
  FROM ts LEFT OUTER JOIN other ON ts.id = other.ts_id

  we can see that other has a column called ts_id, which looks
  exactly like the label that would be made for id in table ts.  so
  thats whats happening here.   so throwing on a use_labels=True to
  the query (or changing the name of ts_id) produces the query:

  SELECT ts.id AS ts_id, ts.dat AS ts_dat, other.ts_id AS other_ts_id,
  other.other_dat AS other_other_dat
  FROM ts LEFT OUTER JOIN other ON ts.id = other.ts_id

  that gives the correct results.

  not sure what SA can really do here to make this kind of issue easier
  to catch, since the resultproxy itself is where its looking for col
  label, col name, , etc.  the generated labels are generally more
  accurate.  i tried playing around with ResultProxy to make it detect
  an ambiguity of this nature, but i think it might not be possible
  unless more flags/switches get passed from the statement to the
  result (which id rather not do since it further marginalizes straight
  textual queries), since if the select statement uses table/col labels
  for each column, there still could be conflicts which dont matter,
  such as the column names the normal eager loader generates:

  'ts_id', 'ts_dat', 'other_4966_ts_id', 'other_4966_other_dat',

  that result is from column ts_id attached to an Alias
  other_4966.  if we said dont allow any Column to be found twice in
  the row, then that breaks (since it will match other_4966_ts_id on
  its _label, ts_id on its name).

  On Feb 27, 2007, at 12:09 PM, Dennis Muhlestein wrote:

  from sqlalchemy import *

  e=create_engine('sqlite://memory')
  ts=Table('ts',e,
 Column ( 'id',Integer,primary_key=True),
 Column ( 'dat',Integer,nullable=False))
  ts.create()

  to_oneornone=Table('other',e,
 Column ( 'ts_id', Integer,ForeignKey('ts.id'), primary_key=True,
  nullable=False ),
 Column ( 'other_dat', Integer, nullable=False ) )
  to_oneornone.create()

  class T(object): pass
  T.mapper=mapper(T,ts)

  class To(object):pass
  To.mapper=mapper(To,to_oneornone,properties={'ts':relation
  (T,backref=backref('other',uselist=False))})

  s=create_session()
  for x in range(10):
   t=T()
   t.dat=x
   s.save(t)

   if x % 2 == 0: # test every other T has an optional data
o=To()
o.other_dat=x
t.other=o

   s.save(t)
   s.flush()

  s.clear()

  somedata=s.query(T).options(eagerload('other')).select()
  print 'Number results should be 10: ', len(somedata)

  s.clear()

  sel=select([ts,to_oneornone],
 

[sqlalchemy] rev2362 fixes one thing and breaks another

2007-02-27 Thread sdobrev
hallo. 
AFAIsee rev 2362 fixes the lazy-load for polymorphic properties.
but is seems to introduce another problem.. or maybe uncover it.

table-inheritance, A-B-C-D, and A has reference to B.

2361: lazy-ref is loaded wrong
...
  File /home/az/src/hor-trunk/db/sawrap/tests/sa_gentestbase.py, 
line 109, in query1
klas.__name__+'.getby_'+idname+'():\n result= %(q)s\n 
expect= %(exp_single)s' % locals()
AssertionError: A.getby_db_id():
 result= A( db_id=1 linkA=cc name=anna )
 expect= A( db_id=1 linkA=ben name=anna )


2362: cannot compile mapper A:
... (inside obj-ctor / mapper compilation) ...
File /usr/lib/python2.4/site-packages/sqlalchemy/orm/properties.py, 
line 341, in _create_polymorphic_joins
raise exceptions.AssertionError(Could not find corresponding 
column for  + str(c) +  in selectable   + 
str(self.mapper.select_table))

AssertionError: Could not find corresponding column for B.db_id in 
selectable SELECT bz4C.db_id, bz4C.name, CAST(NULL AS TEXT) 
AS dataD, bz4C.linkA_id, bz4C.atype, bz4C.dataC, bz4C.dataB 
FROM (SELECT A.linkA_id AS linkA_id, A.name AS name, A.db_id 
AS db_id, A.atype AS atype, B.dataB AS dataB, C.dataC 
AS dataC 
FROM A JOIN B ON B.db_id = A.db_id JOIN C ON C.db_id 
= B.db_id 
WHERE A.atype = ?) AS bz4C UNION ALL 
SELECT bz4B.db_id, bz4B.name, CAST(NULL AS TEXT) 
AS dataD, bz4B.linkA_id, bz4B.atype, CAST(NULL AS TEXT) 
AS dataC, bz4B.dataB 
FROM (SELECT A.linkA_id AS linkA_id, A.name AS name, A.db_id 
AS db_id, A.atype AS atype, B.dataB AS dataB 
FROM A JOIN B ON B.db_id = A.db_id 
WHERE A.atype = ?) AS bz4B UNION ALL 
SELECT D.db_id, A.name, D.dataD, A.linkA_id, A.atype, 
C.dataC, B.dataB 
FROM A JOIN B ON B.db_id = A.db_id JOIN C ON C.db_id 
= B.db_id JOIN D ON D.db_id = C.db_id

FYI, This behaviour happens if A points to a heir of itself of level 
= max-2; e.g. in the case of A-B-C-D-E-F, A pointing to any of B,C,D 
would raise the above, and will not error for A,E,F. Or something 
alike.

===
ciao
svil

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



_test-ABCD-t.py
Description: application/python


sa_gentestbase.py
Description: application/python