[sqlalchemy] The cost of defer()

2013-07-11 Thread Gombas, Gabor
Hi,

I wrote a query joining a couple of tables, returning over a hundred thousand 
rows. Since I only needed to access a couple of the attributes of the returned 
objects for this specific use case, I thought to use a dozen or so 
Query.options(defer(...)) calls to avoid loading the unneeded columns. But to 
my surprise, the query became much slower. Profiling attributed almost all the 
extra time to set_deferred_for_local_state() and LoadDeferredColumns.__init__():

   827855   15.6680.000   27.0680.000 
.../SQLAlchemy-0.8.1-py2.6-linux-x86_64.egg/sqlalchemy/orm/strategies.py:184(set_deferred_for_local_state)
   827855   10.5240.000   10.5240.000 
.../SQLAlchemy-0.8.1-py2.6-linux-x86_64.egg/sqlalchemy/orm/strategies.py:259(__init__)

If defer() is so expensive, then it is not very useful. Would it be possible to 
make it cheaper?

Gabor





NOTICE: Morgan Stanley is not acting as a municipal advisor and the opinions or 
views contained herein are not intended to be, and do not constitute, advice 
within the meaning of Section 975 of the Dodd-Frank Wall Street Reform and 
Consumer Protection Act. If you have received this communication in error, 
please destroy all electronic and paper copies and notify the sender 
immediately. Mistransmission is not intended to waive confidentiality or 
privilege. Morgan Stanley reserves the right, to the extent permitted under 
applicable law, to monitor electronic communications. This message is subject 
to terms available at the following link: 
http://www.morganstanley.com/disclaimers If you cannot access these links, 
please notify us by reply message and we will send the contents to you. By 
messaging with Morgan Stanley you consent to the foregoing.

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.




Re: [sqlalchemy] The cost of defer()

2013-07-11 Thread Michael Bayer
the path would be to figure out if the logic of a per-query defer option can 
somehow be linked to the attribute when it hits its normal refresh logic - if 
those attribute were set up as deferred at the mapper config level (where 
deferred is usually used), you wouldn't see this overhead since the deferred 
loader would be the default callable.But if you only need a few attributes 
why not just go the other way and query for those attributes directly?   that 
would save you way more overhead than even if we removed all overhead from 
defer(), since the most expensive thing is all the mapper identity map logic 
that takes place when full entities are loaded.


On Jul 11, 2013, at 4:02 AM, Gombas, Gabor gabor.gom...@morganstanley.com 
wrote:

 
 Hi,
  
 I wrote a query joining a couple of tables, returning over a hundred thousand 
 rows. Since I only needed to access a couple of the attributes of the 
 returned objects for this specific use case, I thought to use a dozen or so 
 Query.options(defer(…)) calls to avoid loading the unneeded columns. But to 
 my surprise, the query became much slower. Profiling attributed almost all 
 the extra time to set_deferred_for_local_state() and 
 LoadDeferredColumns.__init__():
  
827855   15.6680.000   27.0680.000 
 …/SQLAlchemy-0.8.1-py2.6-linux-x86_64.egg/sqlalchemy/orm/strategies.py:184(set_deferred_for_local_state)
827855   10.5240.000   10.5240.000 
 …/SQLAlchemy-0.8.1-py2.6-linux-x86_64.egg/sqlalchemy/orm/strategies.py:259(__init__)
  
 If defer() is so expensive, then it is not very useful. Would it be possible 
 to make it cheaper?
  
 Gabor
  
 
 
 
 NOTICE: Morgan Stanley is not acting as a municipal advisor and the opinions 
 or views contained herein are not intended to be, and do not constitute, 
 advice within the meaning of Section 975 of the Dodd-Frank Wall Street Reform 
 and Consumer Protection Act. If you have received this communication in 
 error, please destroy all electronic and paper copies and notify the sender 
 immediately. Mistransmission is not intended to waive confidentiality or 
 privilege. Morgan Stanley reserves the right, to the extent permitted under 
 applicable law, to monitor electronic communications. This message is subject 
 to terms available at the following link: 
 http://www.morganstanley.com/disclaimers If you cannot access these links, 
 please notify us by reply message and we will send the contents to you. By 
 messaging with Morgan Stanley you consent to the foregoing.
 
 
 
 
 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to sqlalchemy+unsubscr...@googlegroups.com.
 To post to this group, send email to sqlalchemy@googlegroups.com.
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/groups/opt_out.
  
  

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.




RE: [sqlalchemy] The cost of defer()

2013-07-11 Thread Gombas, Gabor
I did need the objects, not just the raw data, otherwise I'd had to duplicate a 
bunch of existing code which expected full-blown objects to operate on. 
Modifying the mapper is not really an option unless the majority of the users 
have the same requirements, otherwise I end up having to add a huge amount of 
undefer() calls everywhere else (and the query storm caused by missing an 
undefer() would be much more painful). Maybe the documentation of defer() could 
mention that the use of the option can in fact reduce performance, because it's 
not intuitive that loading unneeded data is cheaper than not loading it.

From: sqlalchemy@googlegroups.com [mailto:sqlalchemy@googlegroups.com] On 
Behalf Of Michael Bayer
Sent: 11 July 2013 15:34
To: sqlalchemy@googlegroups.com
Subject: Re: [sqlalchemy] The cost of defer()

the path would be to figure out if the logic of a per-query defer option can 
somehow be linked to the attribute when it hits its normal refresh logic - if 
those attribute were set up as deferred at the mapper config level (where 
deferred is usually used), you wouldn't see this overhead since the deferred 
loader would be the default callable.But if you only need a few attributes 
why not just go the other way and query for those attributes directly?   that 
would save you way more overhead than even if we removed all overhead from 
defer(), since the most expensive thing is all the mapper identity map logic 
that takes place when full entities are loaded.


On Jul 11, 2013, at 4:02 AM, Gombas, Gabor 
gabor.gom...@morganstanley.commailto:gabor.gom...@morganstanley.com wrote:



Hi,

I wrote a query joining a couple of tables, returning over a hundred thousand 
rows. Since I only needed to access a couple of the attributes of the returned 
objects for this specific use case, I thought to use a dozen or so 
Query.options(defer(...)) calls to avoid loading the unneeded columns. But to 
my surprise, the query became much slower. Profiling attributed almost all the 
extra time to set_deferred_for_local_state() and LoadDeferredColumns.__init__():

   827855   15.6680.000   27.0680.000 
.../SQLAlchemy-0.8.1-py2.6-linux-x86_64.egg/sqlalchemy/orm/strategies.py:184(set_deferred_for_local_state)
   827855   10.5240.000   10.5240.000 
.../SQLAlchemy-0.8.1-py2.6-linux-x86_64.egg/sqlalchemy/orm/strategies.py:259(__init__)

If defer() is so expensive, then it is not very useful. Would it be possible to 
make it cheaper?

Gabor




NOTICE: Morgan Stanley is not acting as a municipal advisor and the opinions or 
views contained herein are not intended to be, and do not constitute, advice 
within the meaning of Section 975 of the Dodd-Frank Wall Street Reform and 
Consumer Protection Act. If you have received this communication in error, 
please destroy all electronic and paper copies and notify the sender 
immediately. Mistransmission is not intended to waive confidentiality or 
privilege. Morgan Stanley reserves the right, to the extent permitted under 
applicable law, to monitor electronic communications. This message is subject 
to terms available at the following link: 
http://www.morganstanley.com/disclaimers If you cannot access these links, 
please notify us by reply message and we will send the contents to you. By 
messaging with Morgan Stanley you consent to the foregoing.




--
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to 
sqlalchemy+unsubscr...@googlegroups.commailto:sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to 
sqlalchemy@googlegroups.commailto:sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.



--
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to 
sqlalchemy+unsubscr...@googlegroups.commailto:sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to 
sqlalchemy@googlegroups.commailto:sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.






NOTICE: Morgan Stanley is not acting as a municipal advisor and the opinions or 
views contained herein are not intended to be, and do not constitute, advice 
within the meaning of Section 975 of the Dodd-Frank Wall Street Reform and 
Consumer Protection Act. If you have received this communication in error, 
please destroy all electronic and paper copies and notify the sender 
immediately. Mistransmission is not intended to waive confidentiality or 
privilege. Morgan Stanley reserves the right, to the extent permitted under 
applicable law, to monitor 

Re: [sqlalchemy] SQLAlchemy 0.8.2 released

2013-07-11 Thread Werner

Michael,

On 03/07/2013 22:20, Michael Bayer wrote:

Hey all -

SQLAlchemy release 0.8.2 is now available.

0.8.2 includes several dozen bug fixes and new features, including refinement 
of some of the new features introduced in 0.8.

Areas of improvement include Core, ORM, as well as specific fixes for dialects 
such as Postgresql, MySQL, Oracle, SQL Server, Firebird and Sybase.

Users should carefully review the Changelog 
(http://docs.sqlalchemy.org/en/latest/changelog/changelog_08.html#change-0.8.2) 
to note which behaviors and issues are affected. We'd like to thank the many 
contributors who helped with this release.

SQLAlchemy 0.8.2 is available on the Download Page: 
http://www.sqlalchemy.org/download.html
Thanks for adding the retaining flag for Firebird - you are way to 
fast for me:)

Werner

--
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.




[sqlalchemy] Generated update command is alway schosing alternative field names

2013-07-11 Thread Richard Gomes
hello,

I've previously defined inserts and updates by hand in my application, 
which is working fine, not using SQLAlchemy at the moment.
At this point, I'd like to employ SQLAlchemy to generate these inserts and 
updates for me. And that's all.
I mean: just generate the queries for me. I'm *not* going to execute via 
SQLAlchemy at this point.


I did the test below:

engine = create_engine('postgresql://localhost/sample')
metadata = MetaData()
metadata.bind = engine
t = metadata.tables['company_valuation_measures']
print(str(   t.update().values(trailing_pe=1.0).where(t.c.symbol
=='dummy').where(t.c.date=='dummy')   ))


I obtained:

UPDATE company_valuation_measures
SET trailing_pe=%(trailing_pe)s
WHERE company_valuation_measures.symbol = %(symbol_1)s AND 
company_valuation_measures.date = %(date_1)s


The trouble is: field names are 'symbol' and 'date', not 'symbol_1', not '
date_1'.

Could someone point out what I'm doing wrong?

Thanks

-- Richard

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.




[sqlalchemy] Dogpile caching: can't pickle function objects

2013-07-11 Thread Amir Elaguizy
If I do a query like this:

return PcpPostModel.query.filter_by(id=post_id).options(
FromCache(default)
)

and then later I do another query like this:

PcpPostModel.query.options(FromCache(default)).all()

Any models that were returned by the first query are now of type: class 
'dogpile.cache.api.CachedValue'

So then when the second query runs it will except with:

Traceback (most recent call last):
  File 
/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/runpy.py,
 
line 162, in _run_module_as_main
__main__, fname, loader, pkg_name)
  File 
/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/runpy.py,
 
line 72, in _run_code
exec code in run_globals
  File 
/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/cProfile.py,
 
line 199, in module
main()
  File 
/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/cProfile.py,
 
line 192, in main
runctx(code, globs, None, options.outfile, options.sort)
  File 
/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/cProfile.py,
 
line 49, in runctx
prof = prof.runctx(statement, globals, locals)
  File 
/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/cProfile.py,
 
line 140, in runctx
exec cmd in globals, locals
  File scripts/benchmark_boutpage_queries.py, line 45, in module
for p in post.related_bouts(4):
  File stufff/post/pcp_post_model.py, line 130, in related_bouts
posts = post_query.options(
  File 
/Users/aelaguiz/workspace/stufff/venv/lib/python2.7/site-packages/sqlalchemy/orm/query.py,
 
line 2104, in all
return list(self)
  File stufff/base/caching_query.py, line 71, in __iter__
return self.get_value(createfunc=createfunc)
  File stufff/base/caching_query.py, line 117, in get_value
expiration_time=expiration_time
  File 
/Users/aelaguiz/workspace/stufff/venv/lib/python2.7/site-packages/dogpile/cache/region.py,
 
line 588, in get_or_create
async_creator) as value:
  File 
/Users/aelaguiz/workspace/stufff/venv/lib/python2.7/site-packages/dogpile/core/dogpile.py,
 
line 160, in __enter__
return self._enter()
  File 
/Users/aelaguiz/workspace/stufff/venv/lib/python2.7/site-packages/dogpile/core/dogpile.py,
 
line 100, in _enter
generated = self._enter_create(createdtime)
  File 
/Users/aelaguiz/workspace/stufff/venv/lib/python2.7/site-packages/dogpile/core/dogpile.py,
 
line 151, in _enter_create
created = self.creator()
  File 
/Users/aelaguiz/workspace/stufff/venv/lib/python2.7/site-packages/dogpile/cache/region.py,
 
line 570, in gen_value
self.backend.set(key, value)
  File 
/Users/aelaguiz/workspace/stufff/venv/lib/python2.7/site-packages/dogpile/cache/backends/memcached.py,
 
line 168, in set
**self.set_arguments
  File 
/Users/aelaguiz/workspace/stufff/venv/lib/python2.7/site-packages/bmemcached/__init__.py,
 
line 51, in set
returns.append(server.set(key, value, time))
  File 
/Users/aelaguiz/workspace/stufff/venv/lib/python2.7/site-packages/bmemcached/__init__.py,
 
line 382, in set
return self._set_add_replace('set', key, value, time)
  File 
/Users/aelaguiz/workspace/stufff/venv/lib/python2.7/site-packages/bmemcached/__init__.py,
 
line 358, in _set_add_replace
flags, value = self.serialize(value)
  File 
/Users/aelaguiz/workspace/stufff/venv/lib/python2.7/site-packages/bmemcached/__init__.py,
 
line 273, in serialize
value = dumps(value)
  File /Users/aelaguiz/workspace/stufff/venv/lib/python2.7/copy_reg.py, 
line 70, in _reduce_ex
raise TypeError, can't pickle %s objects % base.__name__
TypeError: can't pickle function objects

Any idea what I can do about this?

Thanks!
Amir

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.




Re: [sqlalchemy] SQLAlchemy 0.8.2 released

2013-07-11 Thread Jonathan Vanasco
On a tangent...

I just noticed that there are several dozen (if not hundreds) of SqlAlchemy 
projects on PyPi

Perhaps SqlAlchemy is now large enough that it should have it's own 
classifier ?

Something like...

Topic :: Database :: Front-Ends :: SqlAlchemy

Topic :: Database :: SqlAlchmey

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.




[sqlalchemy] Re: Dogpile caching: can't pickle function objects

2013-07-11 Thread Jonathan Vanasco
I serialize all my cached data into a dict or json before caching, then 
unserialize into whatever object i need.

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.




Re: [sqlalchemy] The cost of defer()

2013-07-11 Thread Michael Bayer
well what kind of data are we talking about?  defer()'s use case was for binary 
large objects and such, fields that are many K/Megs in size.  if you're 
deferring a bunch of ints, then yes it's not optimized very well for that.

Half of the overhead could be easily fixed here, creating those 
LoadDeferredColumns objects could be offloaded to a later point.The other 
half, setting up that callable, I'd have to spend some time reviewing the use 
cases here.  The difference between an attribute that is deferred vs. one 
that is expired is that if you access some other expired attribute, the 
deferred attribute will still not load - because the use case is, you really 
don't want this BLOB column to load unless you touch it specifically.   So to 
get that instruction into the state, don't load these keys even on an 
unexpire, uses some kind of method call on every state.
InstanceState._set_callable could be inlined more here to do less work, 
instructions up to the loader process just to populate a key in a dictionary 
maybe, though these reorganizations can destabilize the code.   it's not 
something I'd be comfortable doing in 0.8, the ticket I created 
(http://www.sqlalchemy.org/trac/ticket/2778) has any potential work here for 
0.9.

The other way to go here is to provide a query option that explicitly delivers 
the attribute as expired as opposed to deferred, looking at how that works 
right now I can give you the recipe below, but it still involves a function 
call per column so that the InstanceState knows the attribute is expired.


from sqlalchemy.orm.strategies import DeferredOption, DeferredColumnLoader


class DontLoadColumnOption(DeferredOption):
def get_strategy_class(self):
return NoColumnLoader


class NoColumnLoader(DeferredColumnLoader):
def create_row_processor(self, context, path, mapper, row, adapter):
if not self.is_class_level:
def set_deferred_for_local_state(state, dict_, row):
state.callables[self.key] = state
return set_deferred_for_local_state, None, None
else:
return super(NoColumnLoader, self).create_row_processor(
context, path, mapper, row, adapter)

if __name__ == '__main__':
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class A(Base):
__tablename__ = 'a'

id = Column(Integer, primary_key=True)

x = Column(Integer)
y = Column(Integer)
z = Column(Integer)
q = Column(Integer)

e = create_engine(sqlite://, echo=True)
Base.metadata.create_all(e)
s = Session(e)
s.add_all([
A(x=x%d % i, y=y%d % i, z=z%d % i, q=q%d % i)
for i in xrange(1000)
])
s.commit()
s.close()

loaded = s.query(A).options(DontLoadColumnOption(y),
DontLoadColumnOption(z)).order_by(A.id).all()

for a in loaded:
assert 'y' not in a.__dict__
assert 'z' not in a.__dict__
assert 'x' in a.__dict__
assert 'q' in a.__dict__

assert a.z == z%d % (a.id - 1), a.z













On Jul 11, 2013, at 10:23 AM, Gombas, Gabor gabor.gom...@morganstanley.com 
wrote:

 
 I did need the objects, not just the raw data, otherwise I’d had to duplicate 
 a bunch of existing code which expected full-blown objects to operate on. 
 Modifying the mapper is not really an option unless the majority of the users 
 have the same requirements, otherwise I end up having to add a huge amount of 
 undefer() calls everywhere else (and the query storm caused by missing an 
 undefer() would be much more painful). Maybe the documentation of defer() 
 could mention that the use of the option can in fact reduce performance, 
 because it’s not intuitive that loading unneeded data is cheaper than not 
 loading it.
  
 From: sqlalchemy@googlegroups.com [mailto:sqlalchemy@googlegroups.com] On 
 Behalf Of Michael Bayer
 Sent: 11 July 2013 15:34
 To: sqlalchemy@googlegroups.com
 Subject: Re: [sqlalchemy] The cost of defer()
  
 the path would be to figure out if the logic of a per-query defer option can 
 somehow be linked to the attribute when it hits its normal refresh logic - if 
 those attribute were set up as deferred at the mapper config level (where 
 deferred is usually used), you wouldn't see this overhead since the deferred 
 loader would be the default callable.But if you only need a few 
 attributes why not just go the other way and query for those attributes 
 directly?   that would save you way more overhead than even if we removed all 
 overhead from defer(), since the most expensive thing is all the mapper 
 identity map logic that takes place when full entities are loaded.
  
  
 On Jul 11, 2013, at 4:02 AM, Gombas, Gabor gabor.gom...@morganstanley.com 
 wrote:
 
 
  
 Hi,
  
 I wrote a query joining a couple of tables, returning over a hundred 

[sqlalchemy] Join order determinism

2013-07-11 Thread Amir Elaguizy
I noticed that between runs my cache hit rate using dogpile query caching 
could change without any of the underlying data structures changing, after 
digging in what I found was the join order on my polymorphic classes is not 
deterministic. Is there any way to ensure a deterministic join order on 
polymorphic loads?

Examples of the queries being generated:

Run 1:

SELECT entities.id AS entities_id, entities.parent_id AS 
entities_parent_id, entities.type_id AS entities_type_id, entities.name AS 
entities_name, entities.created_at AS entities_created_at, entities.hotness 
AS entities_hotness, entities.hotness_dirty AS entities_hotness_dirty, 
entities.modified_at AS entities_modified_at, entities.up_votes AS 
entities_up_votes, entities.down_votes AS entities_down_votes, 
categories.id AS categories_id, videos.id AS videos_id, 
videos.video_type_id AS videos_video_type_id, videos.poster_id AS 
videos_poster_id, videos.key AS videos_key, clubs.id AS clubs_id, brands.id 
AS brands_id, pcp_points.id AS pcp_points_id, pcp_points.poster_id AS 
pcp_points_poster_id, pcp_points.subject_id AS pcp_points_subject_id, 
pcp_points.is_point AS pcp_points_is_point, pcp_points.body AS 
pcp_points_body, pcp_points.origin_url AS pcp_points_origin_url, tags.id AS 
tags_id, pcp_vote_targets.id AS pcp_vote_targets_id, stufff_images.id AS 
stufff_images_id, stufff_images.image_id AS stufff_images_image_id, 
stufff_images.poster_id AS stufff_images_poster_id, stufff_images.source AS 
stufff_images_source, link_posts.id AS link_posts_id, link_posts.url AS 
link_posts_url, link_posts.edited_at AS link_posts_edited_at, 
link_posts.poster_id AS link_posts_poster_id, users.id AS users_id, 
users.email AS users_email, users.username AS users_username, 
users.first_name AS users_first_name, users.last_name AS users_last_name, 
users.picture AS users_picture, users.origin_url AS users_origin_url, 
users.city AS users_city, users.state AS users_state, users.country AS 
users_country, users.gender AS users_gender, users.password AS 
users_password, users.bio AS users_bio, users.email_verified AS 
users_email_verified, users.email_validation AS users_email_validation, 
users.temp_password AS users_temp_password, users.temp_password_expiry AS 
users_temp_password_expiry, users.active AS users_active, users.admin AS 
users_admin, users.reputation AS users_reputation, text_posts.id AS 
text_posts_id, text_posts.body AS text_posts_body, text_posts.edited_at AS 
text_posts_edited_at, text_posts.poster_id AS text_posts_poster_id, 
products.id AS products_id, pcp_posts.id AS pcp_posts_id, 
pcp_posts.poster_id AS pcp_posts_poster_id, pcp_posts.subject_id_1 AS 
pcp_posts_subject_id_1, pcp_posts.subject_id_2 AS pcp_posts_subject_id_2, 
pcp_posts.vote_id_1 AS pcp_posts_vote_id_1, pcp_posts.vote_id_2 AS 
pcp_posts_vote_id_2, pcp_posts.top_point_id AS pcp_posts_top_point_id, 
comments.id AS comments_id, comments.body AS comments_body, 
comments.poster_id AS comments_poster_id, anon_1.users_id AS 
anon_1_users_id, anon_1.entities_id AS anon_1_entities_id, 
anon_1.entities_parent_id AS anon_1_entities_parent_id, 
anon_1.entities_type_id AS anon_1_entities_type_id, anon_1.entities_name AS 
anon_1_entities_name, anon_1.entities_created_at AS 
anon_1_entities_created_at, anon_1.entities_hotness AS 
anon_1_entities_hotness, anon_1.entities_hotness_dirty AS 
anon_1_entities_hotness_dirty, anon_1.entities_modified_at AS 
anon_1_entities_modified_at, anon_1.entities_up_votes AS 
anon_1_entities_up_votes, anon_1.entities_down_votes AS 
anon_1_entities_down_votes, anon_1.users_email AS anon_1_users_email, 
anon_1.users_username AS anon_1_users_username, anon_1.users_first_name AS 
anon_1_users_first_name, anon_1.users_last_name AS anon_1_users_last_name, 
anon_1.users_picture AS anon_1_users_picture, anon_1.users_origin_url AS 
anon_1_users_origin_url, anon_1.users_city AS anon_1_users_city, 
anon_1.users_state AS anon_1_users_state, anon_1.users_country AS 
anon_1_users_country, anon_1.users_gender AS anon_1_users_gender, 
anon_1.users_password AS anon_1_users_password, anon_1.users_bio AS 
anon_1_users_bio, anon_1.users_email_verified AS 
anon_1_users_email_verified, anon_1.users_email_validation AS 
anon_1_users_email_validation, anon_1.users_temp_password AS 
anon_1_users_temp_password, anon_1.users_temp_password_expiry AS 
anon_1_users_temp_password_expiry, anon_1.users_active AS 
anon_1_users_active, anon_1.users_admin AS anon_1_users_admin, 
anon_1.users_reputation AS anon_1_users_reputation, anon_2.users_id AS 
anon_2_users_id, anon_2.entities_id AS anon_2_entities_id, 
anon_2.entities_parent_id AS anon_2_entities_parent_id, 
anon_2.entities_type_id AS anon_2_entities_type_id, anon_2.entities_name AS 
anon_2_entities_name, anon_2.entities_created_at AS 
anon_2_entities_created_at, anon_2.entities_hotness AS 
anon_2_entities_hotness, anon_2.entities_hotness_dirty AS 
anon_2_entities_hotness_dirty, anon_2.entities_modified_at AS 

Re: [sqlalchemy] The cost of defer()

2013-07-11 Thread Michael Bayer
please try out this patch:

http://www.sqlalchemy.org/trac/attachment/ticket/2778/2778.patch


which refactors this particular system to not require the production of a new 
object per instance, which is the slowest part of this, and also inlines the 
work of assembling the callable.  This should give you 50% or more method call 
improvement.  if this is enough, this might be OK for 0.8.





On Jul 11, 2013, at 1:40 PM, Michael Bayer mike...@zzzcomputing.com wrote:

 well what kind of data are we talking about?  defer()'s use case was for 
 binary large objects and such, fields that are many K/Megs in size.  if 
 you're deferring a bunch of ints, then yes it's not optimized very well for 
 that.
 
 Half of the overhead could be easily fixed here, creating those 
 LoadDeferredColumns objects could be offloaded to a later point.The other 
 half, setting up that callable, I'd have to spend some time reviewing the use 
 cases here.  The difference between an attribute that is deferred vs. one 
 that is expired is that if you access some other expired attribute, the 
 deferred attribute will still not load - because the use case is, you 
 really don't want this BLOB column to load unless you touch it specifically.  
  So to get that instruction into the state, don't load these keys even on an 
 unexpire, uses some kind of method call on every state.
 InstanceState._set_callable could be inlined more here to do less work, 
 instructions up to the loader process just to populate a key in a dictionary 
 maybe, though these reorganizations can destabilize the code.   it's not 
 something I'd be comfortable doing in 0.8, the ticket I created 
 (http://www.sqlalchemy.org/trac/ticket/2778) has any potential work here for 
 0.9.
 
 The other way to go here is to provide a query option that explicitly 
 delivers the attribute as expired as opposed to deferred, looking at how 
 that works right now I can give you the recipe below, but it still involves a 
 function call per column so that the InstanceState knows the attribute is 
 expired.
 
 
 from sqlalchemy.orm.strategies import DeferredOption, DeferredColumnLoader
 
 
 class DontLoadColumnOption(DeferredOption):
 def get_strategy_class(self):
 return NoColumnLoader
 
 
 class NoColumnLoader(DeferredColumnLoader):
 def create_row_processor(self, context, path, mapper, row, adapter):
 if not self.is_class_level:
 def set_deferred_for_local_state(state, dict_, row):
 state.callables[self.key] = state
 return set_deferred_for_local_state, None, None
 else:
 return super(NoColumnLoader, self).create_row_processor(
 context, path, mapper, row, adapter)
 
 if __name__ == '__main__':
 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative import declarative_base
 
 Base = declarative_base()
 
 class A(Base):
 __tablename__ = 'a'
 
 id = Column(Integer, primary_key=True)
 
 x = Column(Integer)
 y = Column(Integer)
 z = Column(Integer)
 q = Column(Integer)
 
 e = create_engine(sqlite://, echo=True)
 Base.metadata.create_all(e)
 s = Session(e)
 s.add_all([
 A(x=x%d % i, y=y%d % i, z=z%d % i, q=q%d % i)
 for i in xrange(1000)
 ])
 s.commit()
 s.close()
 
 loaded = s.query(A).options(DontLoadColumnOption(y),
 DontLoadColumnOption(z)).order_by(A.id).all()
 
 for a in loaded:
 assert 'y' not in a.__dict__
 assert 'z' not in a.__dict__
 assert 'x' in a.__dict__
 assert 'q' in a.__dict__
 
 assert a.z == z%d % (a.id - 1), a.z
 
 
 
 
 
 
 
 
 
 
 
 
 
 On Jul 11, 2013, at 10:23 AM, Gombas, Gabor 
 gabor.gom...@morganstanley.com wrote:
 
 
 I did need the objects, not just the raw data, otherwise I’d had to 
 duplicate a bunch of existing code which expected full-blown objects to 
 operate on. Modifying the mapper is not really an option unless the majority 
 of the users have the same requirements, otherwise I end up having to add a 
 huge amount of undefer() calls everywhere else (and the query storm caused 
 by missing an undefer() would be much more painful). Maybe the documentation 
 of defer() could mention that the use of the option can in fact reduce 
 performance, because it’s not intuitive that loading unneeded data is 
 cheaper than not loading it.
  
 From: sqlalchemy@googlegroups.com [mailto:sqlalchemy@googlegroups.com] On 
 Behalf Of Michael Bayer
 Sent: 11 July 2013 15:34
 To: sqlalchemy@googlegroups.com
 Subject: Re: [sqlalchemy] The cost of defer()
  
 the path would be to figure out if the logic of a per-query defer option can 
 somehow be linked to the attribute when it hits its normal refresh logic - 
 if those attribute were set up as deferred at the mapper config level 
 (where deferred is usually used), you wouldn't see this 

Re: [sqlalchemy] Generated update command is alway schosing alternative field names

2013-07-11 Thread Simon King
On Thu, Jul 11, 2013 at 4:30 PM, Richard Gomes rgomes.i...@gmail.com wrote:
 hello,

 I've previously defined inserts and updates by hand in my application, which
 is working fine, not using SQLAlchemy at the moment.
 At this point, I'd like to employ SQLAlchemy to generate these inserts and
 updates for me. And that's all.
 I mean: just generate the queries for me. I'm not going to execute via
 SQLAlchemy at this point.


 I did the test below:

 engine = create_engine('postgresql://localhost/sample')
 metadata = MetaData()
 metadata.bind = engine
 t = metadata.tables['company_valuation_measures']
 print(str(
 t.update().values(trailing_pe=1.0).where(t.c.symbol=='dummy').where(t.c.date=='dummy')
 ))


 I obtained:

 UPDATE company_valuation_measures
 SET trailing_pe=%(trailing_pe)s
 WHERE company_valuation_measures.symbol = %(symbol_1)s AND
 company_valuation_measures.date = %(date_1)s


 The trouble is: field names are 'symbol' and 'date', not 'symbol_1', not
 'date_1'.

 Could someone point out what I'm doing wrong?


SQLAlchemy uses bind parameters when executing SQL - ie. the values
don't get substituted into the SQL string, but get passed to the
underlying DBAPI module separately. This is generally what you want,
as bind parameters avoid potential SQL-injection security holes.

There is a recipe on the wiki for getting the SQL string with the
parameters inserted, but you should read the warning at the top
carefully and fully understand the dangers:

  http://www.sqlalchemy.org/trac/wiki/UsageRecipes/BindsAsStrings

Hope that helps,

Simon

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.




Re: [sqlalchemy] Generated update command is alway schosing alternative field names

2013-07-11 Thread Michael Bayer

On Jul 11, 2013, at 11:30 AM, Richard Gomes rgomes.i...@gmail.com wrote:

 hello,
 
 I've previously defined inserts and updates by hand in my application, which 
 is working fine, not using SQLAlchemy at the moment.
 At this point, I'd like to employ SQLAlchemy to generate these inserts and 
 updates for me. And that's all.
 I mean: just generate the queries for me. I'm not going to execute via 
 SQLAlchemy at this point.
 
 
 I did the test below:
 
 engine = create_engine('postgresql://localhost/sample')
 metadata = MetaData()
 metadata.bind = engine
 t = metadata.tables['company_valuation_measures']
 print(str(   
 t.update().values(trailing_pe=1.0).where(t.c.symbol=='dummy').where(t.c.date=='dummy')
))
 
 
 I obtained:
 
 UPDATE company_valuation_measures
 SET trailing_pe=%(trailing_pe)s
 WHERE company_valuation_measures.symbol = %(symbol_1)s AND 
 company_valuation_measures.date = %(date_1)s
 
 
 The trouble is: field names are 'symbol' and 'date', not 'symbol_1', not 
 'date_1'.
 
 Could someone point out what I'm doing wrong?

symbol_1 and date_1 are generated bound parameter names, which SQLAlchemy 
will match up to those dummy names which you passed in.  since you aren't 
interested in the automatic linkage of dummy to binds and you're looking for 
binds that have a specific name, you can use bindparam():

t.update().values(...).where(t.c.symbol==bindparam('symbol')).where(t.c.date==bindparam('date'))

however, the update() construct might complain on this as insert()/update() 
both reserve the column name binds for the SET/VALUES clause.   you may need to 
name them something else (like symbol_where or something like that).


-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.




Re: [sqlalchemy] Dogpile caching: can't pickle function objects

2013-07-11 Thread Michael Bayer

On Jul 11, 2013, at 11:43 AM, Amir Elaguizy aelag...@gmail.com wrote:

 If I do a query like this:
 
 return PcpPostModel.query.filter_by(id=post_id).options(
 FromCache(default)
 )
 
 and then later I do another query like this:
 
 PcpPostModel.query.options(FromCache(default)).all()
 
 Any models that were returned by the first query are now of type: class 
 'dogpile.cache.api.CachedValue'

CachedValue is a tuple-based container that contains the actual result you want 
to work with as well as the time that the value was placed in the cache.   Take 
a look at the contents of CachedValue.

 
 So then when the second query runs it will except with:
 
   File /Users/aelaguiz/workspace/stufff/venv/lib/python2.7/copy_reg.py, 
 line 70, in _reduce_ex
 raise TypeError, can't pickle %s objects % base.__name__
 TypeError: can't pickle function objects
 
 Any idea what I can do about this?

something in your model class, or your mapping, or perhaps within some 
SQLAlchemy construct in use, is a callable function that isn't picklable.  
SQLAlchemy itself goes through a lot of trouble to not embed functions in 
mapped instances, however in some cases it's difficult to avoid.  You'd need to 
provide full detail on your classes/mappings, most preferably a fully 
contained, runnable example, in order to determine where this callable is 
present.   


-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.




Re: [sqlalchemy] SQLAlchemy 0.8.2 released

2013-07-11 Thread Michael Bayer
hey i like that idea.  have any friends at pypi ?


On Jul 11, 2013, at 1:13 PM, Jonathan Vanasco jvana...@gmail.com wrote:

 On a tangent...
 
 I just noticed that there are several dozen (if not hundreds) of SqlAlchemy 
 projects on PyPi
 
 Perhaps SqlAlchemy is now large enough that it should have it's own 
 classifier ?
 
 Something like...
 
 Topic :: Database :: Front-Ends :: SqlAlchemy
 Topic :: Database :: SqlAlchmey
 
 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to sqlalchemy+unsubscr...@googlegroups.com.
 To post to this group, send email to sqlalchemy@googlegroups.com.
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/groups/opt_out.
  
  

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.




Re: [sqlalchemy] Dogpile caching: can't pickle function objects

2013-07-11 Thread Amir Elaguizy
Michael,

Thanks for the reply. I understand what you're saying and can go search for 
that. I wonder if you could take a look at my question about join order 
determinism in polymorphic queries?

Thanks,
Amir

On Thursday, July 11, 2013 11:09:50 AM UTC-7, Michael Bayer wrote:


 On Jul 11, 2013, at 11:43 AM, Amir Elaguizy aela...@gmail.comjavascript: 
 wrote: 

  If I do a query like this: 
  
  return PcpPostModel.query.filter_by(id=post_id).options( 
  FromCache(default) 
  ) 
  
  and then later I do another query like this: 
  
  PcpPostModel.query.options(FromCache(default)).all() 
  
  Any models that were returned by the first query are now of type: class 
 'dogpile.cache.api.CachedValue' 

 CachedValue is a tuple-based container that contains the actual result you 
 want to work with as well as the time that the value was placed in the 
 cache.   Take a look at the contents of CachedValue. 

  
  So then when the second query runs it will except with: 
  
File 
 /Users/aelaguiz/workspace/stufff/venv/lib/python2.7/copy_reg.py, line 70, 
 in _reduce_ex 
  raise TypeError, can't pickle %s objects % base.__name__ 
  TypeError: can't pickle function objects 
  
  Any idea what I can do about this? 

 something in your model class, or your mapping, or perhaps within some 
 SQLAlchemy construct in use, is a callable function that isn't picklable. 
  SQLAlchemy itself goes through a lot of trouble to not embed functions in 
 mapped instances, however in some cases it's difficult to avoid.  You'd 
 need to provide full detail on your classes/mappings, most preferably a 
 fully contained, runnable example, in order to determine where this 
 callable is present.   




-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.




Re: [sqlalchemy] Join order determinism

2013-07-11 Thread Michael Bayer
when you say between runs, you mean whole new processes with new mappers, 
right?  there are some memoized sets involved in polymorphic loading, those 
sets should not change order as the program runs but across runs there may be 
some changes in order.to improve this I'd need you to provide a simple test 
case on a new trac ticket - here's kind of a guess as to what might resolve it, 
if you want to try:

--- a/lib/sqlalchemy/orm/mapper.py
+++ b/lib/sqlalchemy/orm/mapper.py
@@ -1798,7 +1798,7 @@ class Mapper(_InspectionAttr):
 while stack:
 item = stack.popleft()
 descendants.append(item)
-stack.extend(item._inheriting_mappers)
+stack.extend(sorted(item._inheriting_mappers, key=lambda m: 
m.class_.__name__))
 return util.WeakSequence(descendants)
 
 def polymorphic_iterator(self):






On Jul 11, 2013, at 2:00 PM, Amir Elaguizy aelag...@gmail.com wrote:

 I noticed that between runs my cache hit rate using dogpile query caching 
 could change without any of the underlying data structures changing, after 
 digging in what I found was the join order on my polymorphic classes is not 
 deterministic. Is there any way to ensure a deterministic join order on 
 polymorphic loads?
 
 Examples of the queries being generated:
 
 Run 1:
 
 SELECT entities.id AS entities_id, entities.parent_id AS entities_parent_id, 
 entities.type_id AS entities_type_id, entities.name AS entities_name, 
 entities.created_at AS entities_created_at, entities.hotness AS 
 entities_hotness, entities.hotness_dirty AS entities_hotness_dirty, 
 entities.modified_at AS entities_modified_at, entities.up_votes AS 
 entities_up_votes, entities.down_votes AS entities_down_votes, categories.id 
 AS categories_id, videos.id AS videos_id, videos.video_type_id AS 
 videos_video_type_id, videos.poster_id AS videos_poster_id, videos.key AS 
 videos_key, clubs.id AS clubs_id, brands.id AS brands_id, pcp_points.id AS 
 pcp_points_id, pcp_points.poster_id AS pcp_points_poster_id, 
 pcp_points.subject_id AS pcp_points_subject_id, pcp_points.is_point AS 
 pcp_points_is_point, pcp_points.body AS pcp_points_body, 
 pcp_points.origin_url AS pcp_points_origin_url, tags.id AS tags_id, 
 pcp_vote_targets.id AS pcp_vote_targets_id, stufff_images.id AS 
 stufff_images_id, stufff_images.image_id AS stufff_images_image_id, 
 stufff_images.poster_id AS stufff_images_poster_id, stufff_images.source AS 
 stufff_images_source, link_posts.id AS link_posts_id, link_posts.url AS 
 link_posts_url, link_posts.edited_at AS link_posts_edited_at, 
 link_posts.poster_id AS link_posts_poster_id, users.id AS users_id, 
 users.email AS users_email, users.username AS users_username, 
 users.first_name AS users_first_name, users.last_name AS users_last_name, 
 users.picture AS users_picture, users.origin_url AS users_origin_url, 
 users.city AS users_city, users.state AS users_state, users.country AS 
 users_country, users.gender AS users_gender, users.password AS 
 users_password, users.bio AS users_bio, users.email_verified AS 
 users_email_verified, users.email_validation AS users_email_validation, 
 users.temp_password AS users_temp_password, users.temp_password_expiry AS 
 users_temp_password_expiry, users.active AS users_active, users.admin AS 
 users_admin, users.reputation AS users_reputation, text_posts.id AS 
 text_posts_id, text_posts.body AS text_posts_body, text_posts.edited_at AS 
 text_posts_edited_at, text_posts.poster_id AS text_posts_poster_id, 
 products.id AS products_id, pcp_posts.id AS pcp_posts_id, pcp_posts.poster_id 
 AS pcp_posts_poster_id, pcp_posts.subject_id_1 AS pcp_posts_subject_id_1, 
 pcp_posts.subject_id_2 AS pcp_posts_subject_id_2, pcp_posts.vote_id_1 AS 
 pcp_posts_vote_id_1, pcp_posts.vote_id_2 AS pcp_posts_vote_id_2, 
 pcp_posts.top_point_id AS pcp_posts_top_point_id, comments.id AS comments_id, 
 comments.body AS comments_body, comments.poster_id AS comments_poster_id, 
 anon_1.users_id AS anon_1_users_id, anon_1.entities_id AS anon_1_entities_id, 
 anon_1.entities_parent_id AS anon_1_entities_parent_id, 
 anon_1.entities_type_id AS anon_1_entities_type_id, anon_1.entities_name AS 
 anon_1_entities_name, anon_1.entities_created_at AS 
 anon_1_entities_created_at, anon_1.entities_hotness AS 
 anon_1_entities_hotness, anon_1.entities_hotness_dirty AS 
 anon_1_entities_hotness_dirty, anon_1.entities_modified_at AS 
 anon_1_entities_modified_at, anon_1.entities_up_votes AS 
 anon_1_entities_up_votes, anon_1.entities_down_votes AS 
 anon_1_entities_down_votes, anon_1.users_email AS anon_1_users_email, 
 anon_1.users_username AS anon_1_users_username, anon_1.users_first_name AS 
 anon_1_users_first_name, anon_1.users_last_name AS anon_1_users_last_name, 
 anon_1.users_picture AS anon_1_users_picture, anon_1.users_origin_url AS 
 anon_1_users_origin_url, anon_1.users_city AS anon_1_users_city, 
 anon_1.users_state AS anon_1_users_state, anon_1.users_country AS 
 

Re: [sqlalchemy] Join order determinism

2013-07-11 Thread Amir Elaguizy
Michael,

That works!

Amir

On Thursday, July 11, 2013 11:17:27 AM UTC-7, Michael Bayer wrote:

 when you say between runs, you mean whole new processes with new 
 mappers, right?  there are some memoized sets involved in polymorphic 
 loading, those sets should not change order as the program runs but across 
 runs there may be some changes in order.to improve this I'd need you to 
 provide a simple test case on a new trac ticket - here's kind of a guess as 
 to what might resolve it, if you want to try:

 --- a/lib/sqlalchemy/orm/mapper.py
 +++ b/lib/sqlalchemy/orm/mapper.py
 @@ -1798,7 +1798,7 @@ class Mapper(_InspectionAttr):
  while stack:
  item = stack.popleft()
  descendants.append(item)
 -stack.extend(item._inheriting_mappers)
 +stack.extend(sorted(item._inheriting_mappers, key=lambda m: 
 m.class_.__name__))
  return util.WeakSequence(descendants)
  
  def polymorphic_iterator(self):






 On Jul 11, 2013, at 2:00 PM, Amir Elaguizy aela...@gmail.comjavascript: 
 wrote:

 I noticed that between runs my cache hit rate using dogpile query caching 
 could change without any of the underlying data structures changing, after 
 digging in what I found was the join order on my polymorphic classes is not 
 deterministic. Is there any way to ensure a deterministic join order on 
 polymorphic loads?

 Examples of the queries being generated:

 Run 1:

 SELECT entities.id AS entities_id, entities.parent_id AS 
 entities_parent_id, entities.type_id AS entities_type_id, entities.nameAS 
 entities_name, entities.created_at AS entities_created_at, 
 entities.hotness AS entities_hotness, entities.hotness_dirty AS 
 entities_hotness_dirty, entities.modified_at AS entities_modified_at, 
 entities.up_votes AS entities_up_votes, entities.down_votes AS 
 entities_down_votes, categories.id AS categories_id, videos.id AS 
 videos_id, videos.video_type_id AS videos_video_type_id, videos.poster_id 
 AS videos_poster_id, videos.key AS videos_key, clubs.id AS clubs_id, 
 brands.id AS brands_id, pcp_points.id AS pcp_points_id, 
 pcp_points.poster_id AS pcp_points_poster_id, pcp_points.subject_id AS 
 pcp_points_subject_id, pcp_points.is_point AS pcp_points_is_point, 
 pcp_points.body AS pcp_points_body, pcp_points.origin_url AS 
 pcp_points_origin_url, tags.id AS tags_id, pcp_vote_targets.id AS 
 pcp_vote_targets_id, stufff_images.id AS stufff_images_id, 
 stufff_images.image_id AS stufff_images_image_id, stufff_images.poster_id 
 AS stufff_images_poster_id, stufff_images.source AS stufff_images_source, 
 link_posts.id AS link_posts_id, link_posts.url AS link_posts_url, 
 link_posts.edited_at AS link_posts_edited_at, link_posts.poster_id AS 
 link_posts_poster_id, users.id AS users_id, users.email AS users_email, 
 users.username AS users_username, users.first_name AS users_first_name, 
 users.last_name AS users_last_name, users.picture AS users_picture, 
 users.origin_url AS users_origin_url, users.city AS users_city, users.state 
 AS users_state, users.country AS users_country, users.gender AS 
 users_gender, users.password AS users_password, users.bio AS users_bio, 
 users.email_verified AS users_email_verified, users.email_validation AS 
 users_email_validation, users.temp_password AS users_temp_password, 
 users.temp_password_expiry AS users_temp_password_expiry, users.active AS 
 users_active, users.admin AS users_admin, users.reputation AS 
 users_reputation, text_posts.id AS text_posts_id, text_posts.body AS 
 text_posts_body, text_posts.edited_at AS text_posts_edited_at, 
 text_posts.poster_id AS text_posts_poster_id, products.id AS products_id, 
 pcp_posts.id AS pcp_posts_id, pcp_posts.poster_id AS pcp_posts_poster_id, 
 pcp_posts.subject_id_1 AS pcp_posts_subject_id_1, pcp_posts.subject_id_2 AS 
 pcp_posts_subject_id_2, pcp_posts.vote_id_1 AS pcp_posts_vote_id_1, 
 pcp_posts.vote_id_2 AS pcp_posts_vote_id_2, pcp_posts.top_point_id AS 
 pcp_posts_top_point_id, comments.id AS comments_id, comments.body AS 
 comments_body, comments.poster_id AS comments_poster_id, anon_1.users_id AS 
 anon_1_users_id, anon_1.entities_id AS anon_1_entities_id, 
 anon_1.entities_parent_id AS anon_1_entities_parent_id, 
 anon_1.entities_type_id AS anon_1_entities_type_id, anon_1.entities_name AS 
 anon_1_entities_name, anon_1.entities_created_at AS 
 anon_1_entities_created_at, anon_1.entities_hotness AS 
 anon_1_entities_hotness, anon_1.entities_hotness_dirty AS 
 anon_1_entities_hotness_dirty, anon_1.entities_modified_at AS 
 anon_1_entities_modified_at, anon_1.entities_up_votes AS 
 anon_1_entities_up_votes, anon_1.entities_down_votes AS 
 anon_1_entities_down_votes, anon_1.users_email AS anon_1_users_email, 
 anon_1.users_username AS anon_1_users_username, anon_1.users_first_name AS 
 anon_1_users_first_name, anon_1.users_last_name AS anon_1_users_last_name, 
 anon_1.users_picture AS anon_1_users_picture, anon_1.users_origin_url AS 
 anon_1_users_origin_url, 

Re: [sqlalchemy] Join order determinism

2013-07-11 Thread Michael Bayer
just that, huh.   the tricky thing is its difficult to ensure that a set() 
doesn't find its way in there at some point and mess the order up again.
open up a ticket for this one I'd need to come up with a test.




On Jul 11, 2013, at 2:19 PM, Amir Elaguizy aelag...@gmail.com wrote:

 Michael,
 
 That works!
 
 Amir
 
 On Thursday, July 11, 2013 11:17:27 AM UTC-7, Michael Bayer wrote:
 when you say between runs, you mean whole new processes with new mappers, 
 right?  there are some memoized sets involved in polymorphic loading, those 
 sets should not change order as the program runs but across runs there may be 
 some changes in order.to improve this I'd need you to provide a simple 
 test case on a new trac ticket - here's kind of a guess as to what might 
 resolve it, if you want to try:
 
 --- a/lib/sqlalchemy/orm/mapper.py
 +++ b/lib/sqlalchemy/orm/mapper.py
 @@ -1798,7 +1798,7 @@ class Mapper(_InspectionAttr):
  while stack:
  item = stack.popleft()
  descendants.append(item)
 -stack.extend(item._inheriting_mappers)
 +stack.extend(sorted(item._inheriting_mappers, key=lambda m: 
 m.class_.__name__))
  return util.WeakSequence(descendants)
  
  def polymorphic_iterator(self):
 
 
 
 
 
 
 On Jul 11, 2013, at 2:00 PM, Amir Elaguizy aela...@gmail.com wrote:
 
 I noticed that between runs my cache hit rate using dogpile query caching 
 could change without any of the underlying data structures changing, after 
 digging in what I found was the join order on my polymorphic classes is not 
 deterministic. Is there any way to ensure a deterministic join order on 
 polymorphic loads?
 
 Examples of the queries being generated:
 
 Run 1:
 
 SELECT entities.id AS entities_id, entities.parent_id AS entities_parent_id, 
 entities.type_id AS entities_type_id, entities.name AS entities_name, 
 entities.created_at AS entities_created_at, entities.hotness AS 
 entities_hotness, entities.hotness_dirty AS entities_hotness_dirty, 
 entities.modified_at AS entities_modified_at, entities.up_votes AS 
 entities_up_votes, entities.down_votes AS entities_down_votes, categories.id 
 AS categories_id, videos.id AS videos_id, videos.video_type_id AS 
 videos_video_type_id, videos.poster_id AS videos_poster_id, videos.key AS 
 videos_key, clubs.id AS clubs_id, brands.id AS brands_id, pcp_points.id AS 
 pcp_points_id, pcp_points.poster_id AS pcp_points_poster_id, 
 pcp_points.subject_id AS pcp_points_subject_id, pcp_points.is_point AS 
 pcp_points_is_point, pcp_points.body AS pcp_points_body, 
 pcp_points.origin_url AS pcp_points_origin_url, tags.id AS tags_id, 
 pcp_vote_targets.id AS pcp_vote_targets_id, stufff_images.id AS 
 stufff_images_id, stufff_images.image_id AS stufff_images_image_id, 
 stufff_images.poster_id AS stufff_images_poster_id, stufff_images.source AS 
 stufff_images_source, link_posts.id AS link_posts_id, link_posts.url AS 
 link_posts_url, link_posts.edited_at AS link_posts_edited_at, 
 link_posts.poster_id AS link_posts_poster_id, users.id AS users_id, 
 users.email AS users_email, users.username AS users_username, 
 users.first_name AS users_first_name, users.last_name AS users_last_name, 
 users.picture AS users_picture, users.origin_url AS users_origin_url, 
 users.city AS users_city, users.state AS users_state, users.country AS 
 users_country, users.gender AS users_gender, users.password AS 
 users_password, users.bio AS users_bio, users.email_verified AS 
 users_email_verified, users.email_validation AS users_email_validation, 
 users.temp_password AS users_temp_password, users.temp_password_expiry AS 
 users_temp_password_expiry, users.active AS users_active, users.admin AS 
 users_admin, users.reputation AS users_reputation, text_posts.id AS 
 text_posts_id, text_posts.body AS text_posts_body, text_posts.edited_at AS 
 text_posts_edited_at, text_posts.poster_id AS text_posts_poster_id, 
 products.id AS products_id, pcp_posts.id AS pcp_posts_id, 
 pcp_posts.poster_id AS pcp_posts_poster_id, pcp_posts.subject_id_1 AS 
 pcp_posts_subject_id_1, pcp_posts.subject_id_2 AS pcp_posts_subject_id_2, 
 pcp_posts.vote_id_1 AS pcp_posts_vote_id_1, pcp_posts.vote_id_2 AS 
 pcp_posts_vote_id_2, pcp_posts.top_point_id AS pcp_posts_top_point_id, 
 comments.id AS comments_id, comments.body AS comments_body, 
 comments.poster_id AS comments_poster_id, anon_1.users_id AS 
 anon_1_users_id, anon_1.entities_id AS anon_1_entities_id, 
 anon_1.entities_parent_id AS anon_1_entities_parent_id, 
 anon_1.entities_type_id AS anon_1_entities_type_id, anon_1.entities_name AS 
 anon_1_entities_name, anon_1.entities_created_at AS 
 anon_1_entities_created_at, anon_1.entities_hotness AS 
 anon_1_entities_hotness, anon_1.entities_hotness_dirty AS 
 anon_1_entities_hotness_dirty, anon_1.entities_modified_at AS 
 anon_1_entities_modified_at, anon_1.entities_up_votes AS 
 anon_1_entities_up_votes, anon_1.entities_down_votes AS 
 anon_1_entities_down_votes, 

Re: [sqlalchemy] Join order determinism

2013-07-11 Thread Amir Elaguizy
http://www.sqlalchemy.org/trac/ticket/2779

On Thursday, July 11, 2013 11:23:32 AM UTC-7, Michael Bayer wrote:

 just that, huh.   the tricky thing is its difficult to ensure that a set() 
 doesn't find its way in there at some point and mess the order up again.   
  open up a ticket for this one I'd need to come up with a test.




 On Jul 11, 2013, at 2:19 PM, Amir Elaguizy aela...@gmail.comjavascript: 
 wrote:

 Michael,

 That works!

 Amir

 On Thursday, July 11, 2013 11:17:27 AM UTC-7, Michael Bayer wrote:

 when you say between runs, you mean whole new processes with new 
 mappers, right?  there are some memoized sets involved in polymorphic 
 loading, those sets should not change order as the program runs but across 
 runs there may be some changes in order.to improve this I'd need you to 
 provide a simple test case on a new trac ticket - here's kind of a guess as 
 to what might resolve it, if you want to try:

 --- a/lib/sqlalchemy/orm/mapper.py
 +++ b/lib/sqlalchemy/orm/mapper.py
 @@ -1798,7 +1798,7 @@ class Mapper(_InspectionAttr):
  while stack:
  item = stack.popleft()
  descendants.append(item)
 -stack.extend(item._inheriting_mappers)
 +stack.extend(sorted(item._inheriting_mappers, key=lambda m: 
 m.class_.__name__))
  return util.WeakSequence(descendants)
  
  def polymorphic_iterator(self):






 On Jul 11, 2013, at 2:00 PM, Amir Elaguizy aela...@gmail.com wrote:

 I noticed that between runs my cache hit rate using dogpile query caching 
 could change without any of the underlying data structures changing, after 
 digging in what I found was the join order on my polymorphic classes is not 
 deterministic. Is there any way to ensure a deterministic join order on 
 polymorphic loads?

 Examples of the queries being generated:

 Run 1:

 SELECT entities.id AS entities_id, entities.parent_id AS 
 entities_parent_id, entities.type_id AS entities_type_id, entities.nameAS 
 entities_name, entities.created_at AS entities_created_at, 
 entities.hotness AS entities_hotness, entities.hotness_dirty AS 
 entities_hotness_dirty, entities.modified_at AS entities_modified_at, 
 entities.up_votes AS entities_up_votes, entities.down_votes AS 
 entities_down_votes, categories.id AS categories_id, videos.id AS 
 videos_id, videos.video_type_id AS videos_video_type_id, videos.poster_id 
 AS videos_poster_id, videos.key AS videos_key, clubs.id AS clubs_id, 
 brands.id AS brands_id, pcp_points.id AS pcp_points_id, 
 pcp_points.poster_id AS pcp_points_poster_id, pcp_points.subject_id AS 
 pcp_points_subject_id, pcp_points.is_point AS pcp_points_is_point, 
 pcp_points.body AS pcp_points_body, pcp_points.origin_url AS 
 pcp_points_origin_url, tags.id AS tags_id, pcp_vote_targets.id AS 
 pcp_vote_targets_id, stufff_images.id AS stufff_images_id, 
 stufff_images.image_id AS stufff_images_image_id, stufff_images.poster_id 
 AS stufff_images_poster_id, stufff_images.source AS stufff_images_source, 
 link_posts.id AS link_posts_id, link_posts.url AS link_posts_url, 
 link_posts.edited_at AS link_posts_edited_at, link_posts.poster_id AS 
 link_posts_poster_id, users.id AS users_id, users.email AS users_email, 
 users.username AS users_username, users.first_name AS users_first_name, 
 users.last_name AS users_last_name, users.picture AS users_picture, 
 users.origin_url AS users_origin_url, users.city AS users_city, users.state 
 AS users_state, users.country AS users_country, users.gender AS 
 users_gender, users.password AS users_password, users.bio AS users_bio, 
 users.email_verified AS users_email_verified, users.email_validation AS 
 users_email_validation, users.temp_password AS users_temp_password, 
 users.temp_password_expiry AS users_temp_password_expiry, users.active AS 
 users_active, users.admin AS users_admin, users.reputation AS 
 users_reputation, text_posts.id AS text_posts_id, text_posts.body AS 
 text_posts_body, text_posts.edited_at AS text_posts_edited_at, 
 text_posts.poster_id AS text_posts_poster_id, products.id AS 
 products_id, pcp_posts.id AS pcp_posts_id, pcp_posts.poster_id AS 
 pcp_posts_poster_id, pcp_posts.subject_id_1 AS pcp_posts_subject_id_1, 
 pcp_posts.subject_id_2 AS pcp_posts_subject_id_2, pcp_posts.vote_id_1 AS 
 pcp_posts_vote_id_1, pcp_posts.vote_id_2 AS pcp_posts_vote_id_2, 
 pcp_posts.top_point_id AS pcp_posts_top_point_id, comments.id AS 
 comments_id, comments.body AS comments_body, comments.poster_id AS 
 comments_poster_id, anon_1.users_id AS anon_1_users_id, anon_1.entities_id 
 AS anon_1_entities_id, anon_1.entities_parent_id AS 
 anon_1_entities_parent_id, anon_1.entities_type_id AS 
 anon_1_entities_type_id, anon_1.entities_name AS anon_1_entities_name, 
 anon_1.entities_created_at AS anon_1_entities_created_at, 
 anon_1.entities_hotness AS anon_1_entities_hotness, 
 anon_1.entities_hotness_dirty AS anon_1_entities_hotness_dirty, 
 anon_1.entities_modified_at AS anon_1_entities_modified_at, 
 

Re: [sqlalchemy] Generated update command is alway schosing alternative field names

2013-07-11 Thread Richard Gomes

Hello Michael,

Thanks a lot for your help :)
I've followed your directions. it works.

Regarding the reserved column names (now I remember I saw this 
yesterday) ... it does not happen because I'm restricting the field 
names which appear in the SET clause, so that there's no collision 
between what appears in the WHERE clause and what appears in the SET clause.



This is the entire recipe, for the records:


from sqlalchemy import create_engine, MetaData, bindparam
engine = create_engine('postgresql://localhost/sample' 
postgresql://localhost/sample%27)

metadata = MetaData()
metadata.bind = engine
metadata.reflect()
t = metadata.tables['company_valuation_measures']
print(str(   
t.update().values(trailing_pe='dummy').where(t.c.symbol==bindparam('symbol')).where(t.c.date==bindparam('date')) 
))


It prints

UPDATE company_valuation_measures SET trailing_pe=%(trailing_pe)s WHERE 
company_valuation_measures.symbol = %(symbol)s AND 
company_valuation_measures.date = %(date)s



Cheers

Richard Gomes
http://rgomes.info
+44(77)9955-6813

On 11/07/13 19:06, Michael Bayer wrote:


On Jul 11, 2013, at 11:30 AM, Richard Gomes rgomes.i...@gmail.com 
mailto:rgomes.i...@gmail.com wrote:



hello,

I've previously defined inserts and updates by hand in my 
application, which is working fine, not using SQLAlchemy at the moment.
At this point, I'd like to employ SQLAlchemy to generate these 
inserts and updates for me. And that's all.
I mean: just generate the queries for me. I'm /*not*/ going to 
execute via SQLAlchemy at this point.



I did the test below:

engine = create_engine('postgresql://localhost/sample' 
postgresql://localhost/sample%27)

metadata = MetaData()
metadata.bind = engine
t = metadata.tables['company_valuation_measures']
print(str(   
t.update().values(trailing_pe=1.0).where(t.c.symbol=='dummy').where(t.c.date=='dummy')   
))



I obtained:

UPDATE company_valuation_measures
SET trailing_pe=%(trailing_pe)s
WHERE company_valuation_measures.symbol = %(symbol_1)s AND 
company_valuation_measures.date = %(date_1)s



The trouble is: field names are 'symbol' and 'date', not 'symbol_1', 
not 'date_1'.


Could someone point out what I'm doing wrong?


symbol_1 and date_1 are generated bound parameter names, which 
SQLAlchemy will match up to those dummy names which you passed in. 
 since you aren't interested in the automatic linkage of dummy to 
binds and you're looking for binds that have a specific name, you can 
use bindparam():


t.update().values(...).where(t.c.symbol==bindparam('symbol')).where(t.c.date==bindparam('date'))

however, the update() construct might complain on this as 
insert()/update() both reserve the column name binds for the 
SET/VALUES clause.   you may need to name them something else (like 
symbol_where or something like that).



--
You received this message because you are subscribed to a topic in the 
Google Groups sqlalchemy group.
To unsubscribe from this topic, visit 
https://groups.google.com/d/topic/sqlalchemy/DtqNcKvr0Yo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to 
sqlalchemy+unsubscr...@googlegroups.com.

To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.




--
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.




[sqlalchemy] Re: best practice for SqlAlchemy and webapps ?

2013-07-11 Thread Jonathan Vanasco
Mike, thanks again.  I finally found time to integrate your 
recommendations.   https://github.com/jvanasco/pyramid_sqlassist

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.




[sqlalchemy] Retreiving datetime(6) value using sqlalchemy

2013-07-11 Thread Matt
Hi all,

I have been writing to my database using func.now(6) for datetime(6) valued 
columns and it has worked perfectly.  However, I've recently run into an 
issue with querying for these values.  It would appear that every time I 
query for the values in datetime(6) columns it returns None.

Examples of datetime(6) values: 


   - '2013-07-10 17:22:49.113604'
   - '2013-07-10 17:55:08.920235'
   

Attempts at retrieving datetime(6) values from the database:

*python:*
print self.engine.execute(select now()).scalar()
print self.engine.execute(select now(6)).scalar()

*output:*
2013-07-11 16:33:04
None

and same thing happens when retrieving an entire row from a table. I didn't 
think it was necessary to go into that sort of detail as I'm hoping this is 
an easy fix, but if need be I can show parts of my schema and datamodel 
along with queries and results for those records.

Any insight would be great.
Thanks,
Matt

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.




[sqlalchemy] Re: Retreiving datetime(6) value using sqlalchemy

2013-07-11 Thread Matt
Sorry, forgot to mention this is for mysql.

http://dev.mysql.com/doc/refman/5.6/en/fractional-seconds.html

On Thursday, July 11, 2013 4:38:03 PM UTC-4, Matt wrote:

 Hi all,

 I have been writing to my database using func.now(6) for datetime(6) 
 valued columns and it has worked perfectly.  However, I've recently run 
 into an issue with querying for these values.  It would appear that every 
 time I query for the values in datetime(6) columns it returns None.

 Examples of datetime(6) values: 


- '2013-07-10 17:22:49.113604'
- '2013-07-10 17:55:08.920235'


 Attempts at retrieving datetime(6) values from the database:

 *python:*
 print self.engine.execute(select now()).scalar()
 print self.engine.execute(select now(6)).scalar()

 *output:*
 2013-07-11 16:33:04
 None

 and same thing happens when retrieving an entire row from a table. I 
 didn't think it was necessary to go into that sort of detail as I'm hoping 
 this is an easy fix, but if need be I can show parts of my schema and 
 datamodel along with queries and results for those records.

 Any insight would be great.
 Thanks,
 Matt


-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.