[sqlalchemy] Re: Problem with using global metadata/connection in a threaded context

2007-05-18 Thread Sébastien LELONG

 Currently, I create a single instance of my persistence layer API,
 which makes a call to global_connect(), and optionally to
 default_metadata.create_all() (for tests). I then pass this instance
 to all the threads that need to talk to my database.

global_connect() uses a DynamicMetadata, which is thread-specific: you need to 
define it each time a new thread is created. Depending on the architecture, 
you might want to add a func called on each thread (eg. on_start_thread_list 
within cherrypy,...) which will do the job. It would look like (not tested):

import sqlalchemy as sa
# blabla
def init_thread():
if sa.default_metadata.is_bound():
pass # ok, thread is already init'
else:
sa.global_connect()
# assert sa.default_metadata.is_bound() == True


Hope that helps.

Cheers
Seb

-- 
Sébastien LELONG
sebastien.lelong[at]sirloon.net
http://www.sirloon.net
http://sirbot.org

--~--~-~--~~~---~--~~
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: @property

2007-04-18 Thread Sébastien LELONG

 I know that I could use a mapper extension for this (with before_insert,
 before_update, etc) but could it not be possible to do it with my
 @property ?

I think when SA apply the mapper (that is, assign), it overrides your property 
definition. You can ensure that by tracking if your property code is called.
 When I need to do that, I rename the original property in the mapper:

assign_mapper(Bla,blabla,properties=dict(_score=blabla.c.score))

and then deal with _score within the property code. One problem is now, your 
mapper doesn't have any score attribute, so your selects need to be aware of 
this and work with _score.

Hope that helps  cheers

Seb
-- 
Sébastien LELONG
http://www.sirloon.net
sebastien.lelong[at]sirloon.net

--~--~-~--~~~---~--~~
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 many-to-many on the same table?

2007-04-04 Thread Sébastien LELONG
Hi,

 Hi, This is causing very messy code though, especially if youa re
 deleteing an article.
 Here is now i have it now. The flush is needed,  
 or else i get an AssertionError saying SA is trying to flush 0 into a
 primary_key.

Could you give more details ? I tried using the previous attached code, seems 
to work nice:

c = Article.get(###)
c.delete()
c.flush()   # delete article and its article_related

You can find this code in attachment.

You may also want to play with backrefs if you just want to have a reference 
to the relater in the related article (A relates to B, B would have 
reference to A without saying B relates to A)


Hope that helps

Cheers,

Seb
-- 
Sébastien LELONG
http://www.sirloon.net
sebastien.lelong[at]sirloon.net

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



articles.py
Description: application/python


[sqlalchemy] Re: DynamicMetaData question

2007-03-14 Thread Sébastien LELONG

 Hey list, are you confused by the current system ?  Please let me know.
 the only change I would favor here would be to merge connect into
 MetaData, BoundMetaData and DynamicMetaData stay around for backwards
 compat for probably forever.

Not actually confused by the system. Since I need to define the connection 
parameter in a seperate file (config file), I *need* the DND.connect() 
method. So, DND is the only I use... The global_connect() is not useful for 
me since I need multiple datasources. Again, beeing able to define connection 
parameter later is crucial, so having a MetaData.connect() would be great.

but I need to get at least 20 or 30 users on this list telling me how  
 they are using metadata.

A typical initialization of my models looks like:

_metadata = DynamicMetaDate(I'll be bound later...)
one_table = Table(blabla,_metadata, ...)

_engine = None
def init_model(dburi,**kwargs):
global _engine
if _engine:
# Engine already defined
# check if metadata bound
if _metadata.is_bound():
# nothing to do   
pass
else:
# need to connect metadata.
# occurs when starting new thread
_metadata.connect(_engine)
else:
   # first we access the model, init everything
_engine = sa.create_engine(dburi,**kwargs)
settlement_metadata.connect(_engine)



BTW, I'd posted on the TG list to know how they handle multiple datasources 
with SA. Answer was for now, only one datasource [probably due to 
global_connect], we'll see next release). So maybe global_connect will not 
even be used anymore by TG...


Cheers


Seb
-- 
Sébastien LELONG
sebastien.lelong[at]sirloon.net
http://www.sirloon.net


--~--~-~--~~~---~--~~
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: DynamicMetaData question

2007-03-13 Thread Sébastien LELONG

 [...] I couldn't use BoundMetaData because I don't know the
 connection parameters until much after import time, so I am using the
 only other option I know of, which is DynamicMetaData [...]. 

I have exactly the same problem. One option is to use global_connect and 
default_metadata (doc: Using the global Metadata object), but as my apps 
are essentially  multi-sources, I need to define datasources separatly. And I 
definitly cannot use the BoundMetaData and hardcode the connection 
parameters... So I'm using the DynamicMetaData and its connect method. Seems 
to be two independant features in this DynamicMetaData...


Seb
-- 
Sébastien LELONG
sebastien.lelong[at]sirloon.net
http://www.sirloon.net

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

2007-03-05 Thread Sébastien LELONG

 I need to ping the Mysql database to keep it alive.

 Is there a simple way to do this with SA?

Maybe you'd want to have a look at the pool_recycle argument of 
create_engine. It'll make the connection pool beeing checked if active, and 
potentially recycle the connections if they are too old. Search for MySQL 
has gone away, you'll have different threads talking about that.


Hope it helps.

Seb
-- 
Sébastien LELONG
sebastien.lelong[at]sirloon.net
http://www.sirloon.net

--~--~-~--~~~---~--~~
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: Get error: 'list' object has no attribute 'accept_visitor'

2007-02-20 Thread Sébastien LELONG

 select_columns = [table.c.col1, table.c.col2]

 statement = table.select(select_columns)

You probably want to:

select_columns = [table.c.col1, table.c.col2]
statement = sqlalchemy.select(select_columns)
res = statement.execute().fetchall() # or the like...

The table.select form you try to get working is used to specify eg. where 
clauses, not to specify which columns to get.


-- 
Sébastien LELONG
sebastien.lelong[at]sirloon.net

On Tuesday 20 February 2007 16:10, vinjvinj wrote:
 I'm getting the following error when I build the select clause.

 select_columns = [table.c.col1, table.c.col2]

 statement = table.select(select_columns)
   File build\bdist.win32\egg\sqlalchemy\sql.py, line 1351, in select
   File build\bdist.win32\egg\sqlalchemy\sql.py, line 65, in select
   File build\bdist.win32\egg\sqlalchemy\sql.py, line 1503, in
 __init__
   File build\bdist.win32\egg\sqlalchemy\sql.py, line 1575, in
 append_whereclause
   File build\bdist.win32\egg\sqlalchemy\sql.py, line 1581, in
 _append_condition
 AttributeError: 'list' object has no attribute 'accept_visitor'

 Any idea what this means?

 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: improving connection resiliency

2007-02-09 Thread Sébastien LELONG

 I am wondering if there isn't a better way to handle connection issues
 than how I am doing it (see the sample below)?

You should give a try with SA 0.3.3 (at least), since several connection 
problems have been solved.

See thread MySQL has gone way. Although it talks about MySQL, the bugfix is 
about the connection pool/object: 
http://groups.google.com/group/sqlalchemy/browse_thread/thread/9412808e695168ea/93ac328e84206c4b

More precisely, also have a look at this thread  How to regenerate 
connections in the QueuePool. You'll find a test case which 
reconnects/regenerates connections when the database goes down:
http://groups.google.com/group/sqlalchemy/browse_thread/thread/f8f5a86ed26d19a7/857f4c70371ea96d
FWIW, you'll find a example of retry mechanism which handle database 
recovering (well, actually, this code is not that clean...).

Finally, IIRC, be aware databases exceptions encapulsation into SA's exception 
has been improved since 0.2.8: some weren't caught resulting in a raise of 
the original, underlying database exceptions.

Hope it helps,

Cheers

Seb
-- 
Sébastien LELONG
sebastien.lelong[at]sirloon.net

--~--~-~--~~~---~--~~
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: new setuptools vs local SA copy

2007-02-07 Thread Sébastien LELONG

 [...] I challenged him to name *any* scenario where an
 administrator would want a local-environment-based PYTHONPATH to be
 overridden by an application-wide configuration and he didnt reply to
 that one.  he sees it as a if youre using .eggs, then you must accept
 that PYTHONPATH only points to installation directories, not runtime
 directories...so basically breaking PYTHONPATH's documented behavior
 into something repurposed is by design.
I completely agree. I too have spent a lot of time finding why my PYTHONPATH 
was not considered anymore. Having it overridden is definitly not the 
expected behavior.

-- 
Sébastien LELONG
sebastien.lelong[at]sirloon.net



--~--~-~--~~~---~--~~
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: making crud with assign_mapper

2007-02-07 Thread Sébastien LELONG

 Thanks. I've been using the inspect module but there's such a lot in
 there it's a bit dizzying!
FWIW, you can also use ipython and its dynamic object introspection, 
completion, etc... This helps a *lot* finding what you want. It's also 
usefull to dive into the sources, precisely where you want, since you can 
invoke the edit command on several python object. Give a try with:

In [9]: edit mytable.__class__.columns


Seb
-- 
Sébastien LELONG
sebastien.lelong[at]sirloon.net

--~--~-~--~~~---~--~~
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: list of strings/unicode strings

2007-02-07 Thread Sébastien LELONG
 Is there anyway I can specify the list of tags like this, instead?

 book.tags = [upython, uprogramming]

Well you could use a PickleType column in your book table... Of course, you'll 
loose functionnalities you could have using a real Tag object. The problem is 
how you consider a tag in your model...

See attachment for the pickletype col.

Hope it helps.

Cheers, 

Seb
-- 
Sébastien LELONG
sebastien.lelong[at]sirloon.net

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



with_pickletype.py
Description: application/python


[sqlalchemy] Re: got problems where map to selectable

2007-02-06 Thread Sébastien LELONG

If you put a refresh just before your assert, that is working:

...
user = session.query(User).selectone_by(name='user1')
session.refresh(user)# here !
assert user.post_count==2, 'user.post_count is %s'%user.post_count

Not sure to understand why though... I bet its because of SA's cache 
(identity_map). Since the user was already loaded before, SA doesn't 
re-perform sql access to the db. You can see it by activating engine.echo = 
True, and selecting users by id (eg. session.query(User).get(1))

Hope it helps.

Cheers,

Seb
-- 
Sébastien LELONG
sebastien.lelong[at]sirloon.net

--~--~-~--~~~---~--~~
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: access mapper properties

2007-02-05 Thread Sébastien LELONG

 In [1]: oo=Tariffa().select(limit=1)[0]
 In [2]: for jjj in oo.c: print jjj.name
 codice
 aliquota_iva
 aliquota_enpav
 centro_costo
 cod_funzione_calcolo
 unita_misura

oo.c will iterate over the attributes of the mapped table. You can iterate 
over all attributes, including relations defined in mappers, with:

for one_attr in oo.mapper.props.keys():
print getattr(oo,one_attr)

Not sure however if that's the correct way...


For mapper only properties, you canget them with:
mapper_props =  oo.mapper.properties.keys()

Actually, oo.mapper.props.keys() is the (almost) concatenation of table + 
mapper properties since:
set(sorted(cl.c.keys() + cl.mapper.properties.keys())) == 
set(sorted(cl.mapper.props.keys()))
= True


Hope it helps.

Cheers,

Seb
-- 
Sébastien LELONG
sebastien.lelong[at]sirloon.net

--~--~-~--~~~---~--~~
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: Inspect and __init__ of a mapped class

2007-02-05 Thread Sébastien LELONG

 btw if u find a way to obtain some externaly-bound non-global
 reference from func's code (see what dis.dis() shows), DO mail...
Bot sure to understand precisely what you want to do, but it seems like monkey 
patching:

class Klass(object):
def incredible_func(self):
a = 2
print a: %s % a

o = Klass()
o.incredible_func() # a: 2

def awesome_func(self):
b = 17
print b: %s % b

Klass.incredible_func = awesome_func

another_o =  Klass()
o.incredible_func() # b: 17


It implies rewriting the whole body func, not just find/replace as in your 
example. Maybe that's what you want to avoid...


Seb
-- 
Sébastien LELONG
sebastien.lelong[at]sirloon.net



 

--~--~-~--~~~---~--~~
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: ORM ramblings 2 - and announcing some o2r wrapper

2007-01-24 Thread Sébastien LELONG

Having a sqlalchemy.__version__ and revision (or whatever named vars) is 
definitly usefull, even more when there are frequent project releases such as 
with SA.
+1 for this feature...

 Maybe just add one simple .revision as of svn's $Revision$, that
 should be okay for flying on devel.
But the file where you put this $Revision$ property has to be changed on every 
commit so the property is updated, no ? If so, this would give wrong revision 
number...


 but u'll need to setup a svn autoprop for that, add . ~/.subversion
 [miscellany]
 enable-auto-props = yes
 [auto-props]
 *.py = svn:keywords=Id Revision
You can also: 

svn propset svn:keywords Revision the_file_you_want_to_tag

avoiding the autoprop for all files.


Cheers,

Seb
-- 
Sébastien LELONG
[EMAIL PROTECTED]

--~--~-~--~~~---~--~~
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] Row attributes from a table with renamed columns

2007-01-23 Thread Sébastien LELONG
Dear SQLAlchemists,

I'm trying to fetch some specific row attributes from a select statement on a 
table. So far so good, this shouldn't be a problem... except this table 
declares some renamed columns, using key, as:

sa.Column('the_label', sa.String(30), key='label')

When I'm inserting rows, the insert statement uses the renamed column 
(label):

one_table.insert().execute(id=0,label='oula')

But when I'm selecting results and fetch some attributes on a given row, only 
the original column names remain:

one_row = one_table.select().execute().fetchall()[0]
print attr = %s % one_row .label  # error !
print orig attr = %s % one_row the_label # ok it works...


Is there any way to get the renamed columns on a RowProxy object ?


As attachment, a test case:

$ python table_with_key.py
Keys in row: ['id', 'the_label']
r.the_label: blabla
Traceback (most recent call last):
  File table_with_key.py, line 25, in ?
print r.label: %s % r.label   # won' work
  File build/bdist.linux-i686/egg/sqlalchemy/engine/base.py, line 730, in 
__getattr__
AttributeError: label


Thanks  Cheers

Seb
-- 
Sébastien LELONG
sebastien.lelong[at]sirloon.net

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



table_with_key.py
Description: application/python


[sqlalchemy] Re: count(*) function

2007-01-15 Thread Sébastien LELONG



I have tried

select([func.count(*)], from_obj=[table_name]).execute()

but it didn't work


I think you should try to specify a column in your count or leave it empty 
(didn't try). If you're using mapped objects, you can use the SelectResults 
extension:


from sqlalchemy.ext.selectresults import SelectResults
SelectResults(your_session.query(YourMappedClass)).count()


Cheers,

Seb
--
Sébastien LELONG
sebastien.lelong[at]sirloon.net

--~--~-~--~~~---~--~~
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: Performance of data mapping and plain access

2006-12-28 Thread Sébastien LELONG



one thing that could make ORM loads much faster would be if you knew
the objects would not need to be flushed() at a later point, and you
disabled history tracking on those instances.  this would prevent the
need to create a copy of the object's attributes at load time.


This reminds me a functionality I was looking for a few weeks ago. I'd liked 
to be able to load read-only objects from a database. Read-only objects were 
(are still) useful for me when retrieving data from a precious database 
(production db), ensuring no update/insert/delete operations would occur. 
Another scenario is an app which can actually do these operations, and 
another app which musn't. While this can be done using grants, it could be 
useful (and easier) if things could be done at the ORM level.


Is there any other way to get those read-only objects, without implementing 
this functionality ?


Cheers,

--
Sébastien LELONG
sebastien.lelong[at]sirloon.net

--~--~-~--~~~---~--~~
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: Performance of data mapping and plain access

2006-12-28 Thread Sébastien LELONG



[...]  simpliest thing
would be to use a Session that has flush() overidden. or an engine that
overrides execute() to check for INSERT/UPDATE/DELETE statements and
throws an error [...]


I tried the ReadOnlySession class which overrides the flush() func. Works like 
a charm, this adds a security net in my apps as I cannot actually even add 
any grants, so this is very useful for me. Thanks.


Moreover, in the 2nd scenario, if app #1 can insert rows and app #2 can't, 
this means there must be different db users (per app) with specific grants 
for each, which adds complexity and may results in an evil maintainance... 



Cheers,

--
Sébastien LELONG
sebastien.lelong[at]sirloon.net

--~--~-~--~~~---~--~~
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: SA 0.3.x: performance issues = proposal

2006-12-08 Thread Sébastien LELONG
As attachement, here's the patch (against rev 2132). It's local to 
sqlalchemy/orm/, so:

cd /sqlalchemy/orm
patch -p0  attribute_cache.patch


About the patch itself:
 1. the cache should be a WeakKeyDictionary
OK, done. Performances are still OK, differences between built-in dict are 
negligible.

 2. the cache needs to be cleared for a particular cache (class ?)
If I understand right, while calling register_attribute(), the cache will be 
cleared for the given class, if this one has been cached. Is there anywhere 
else the cache needs to cleared ?

 3. the cache should *probably* be at the module level, and not within
 the AttributeManager itself; SA uses only a single AttributeManager per
 application so it probably doesnt matter
I let the cache within the AttributeManager... Things can be moved at the 
module level, but if it's not necessary right now, it might not be a good 
idea to do it right now (when it will be necessary, the design may have been 
changed and modifications not valid anymore).

 4. the raise should use an exception class of some kind
I've made it raise a TypeError... Yes, string based exceptions are very a bad 
thing !


Attributes are cached while using the managed_attributes() *and* 
noninherited_managed_attributes() funcs. Those are very similar. I hesitated 
refactor them, but centralize cache management is probably a good thing. This 
is the purpose of the second patch, which include this refactoring. As 
expected, performances decrease. Here's the traditionnal benchmark results:

SA 0.3.1, rev 2127:
total time 4.29376721382

real0m5.420s
user0m4.088s
sys 0m0.108s

SA with attr. cache, no refactoring (~2X faster, back closed to 0.2.8 
speed):
total time 2.34819602966

real0m3.013s
user0m2.344s
sys 0m0.088s

SA with attr. cache, with refactoring (30% slower than without 
refactoring)
total time 3.05679416656

real0m3.747s
user0m2.988s
sys 0m0.068s


It's up to you choosing the patch ! IMO, I'm *not* in favor to use refactoring 
in this case :). 

Finally, I've put a clear_attribute_cache func which, ... clear the attribute 
cache. While client code may not have to worry about caching, it may need to 
clear it...


 thanks much, this is the kind of user involvement i like.
Well, you're very welcome ! Glad to help !


Cheers,

Seb
-- 
Sébastien LELONG
sebastien.lelong[at]sirloon.net


P.S:

 im beginning
 to suspect that yield introduces overhead vs. a straight list ?
 (python interpreter storing stack frames ?  dunno).
dunnotoo :)


--~--~-~--~~~---~--~~
 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
-~--~~~~--~~--~--~---
Index: attributes.py
===
--- attributes.py	(révision 2132)
+++ attributes.py	(copie de travail)
@@ -609,8 +609,18 @@
 
 class AttributeManager(object):
 allows the instrumentation of object attributes.  AttributeManager is stateless, but can be
-overridden by subclasses to redefine some of its factory operations.
+overridden by subclasses to redefine some of its factory operations. Also be aware AttributeManager
+will cache attributes for a given class, allowing not to determine those for each objects (used
+in managed_attributes() and noninherited_managed_attributes()). This cache is cleared for a given class
+while calling register_attribute(), and can be cleared using clear_attribute_cache()
 
+def __init__(self):
+# will cache attributes, indexed by class objects
+self._attribute_cache = weakref.WeakKeyDictionary()
+
+def clear_attribute_cache(self):
+self._attribute_cache.clear()
+
 def rollback(self, *obj):
 retrieves the committed history for each object in the given list, and rolls back the attributes
 each instance to their original value.
@@ -639,21 +649,31 @@
 
 def managed_attributes(self, class_):
 returns an iterator of all InstrumentedAttribute objects associated with the given class.
+if self._attribute_cache.has_key(class_):
+return self._attribute_cache[class_]
+
+self._attribute_cache[class_] = []   
 if not isinstance(class_, type):
-raise repr(class_) +  is not a type
+raise TypeError(repr(class_) +  is not a type)
 for key in dir(class_):
 value = getattr(class_, key, None)
 if isinstance(value

[sqlalchemy] Re: MySQL Has Gone Away

2006-12-07 Thread Sébastien LELONG

 I'm still having this problem with MySQL (both 4.1 and 5.0), SA
 (tested with both 0.2.8 and 0.3.1) and TurboGears 1.0b1.

Almost the same for me (MySQL 5.0.22, SA 0.2.8 and 0.3.1, using CherryPy). 
Using pool_recycle works nice on a non-high load environments. But while I 
benchmark my app (using siege or ab), this always produces Lost connection 
during MySQL query..., and sometimes MySQL server has gone away 

Note the version of MySQLdb is important: using 1.2.2b1 (didn't tested the 
last 1.2.2b2) can reduce those errors, but not completely though. Also, 
MySQLdb is not thread-safe, so using it in a multithreaded environment can be 
painful... (but I'm sure that's transparent using TG).

Since SA 0.2.4 (pool_recycle did not exist at this time), I use a specific 
pool, derived from the QueuePool class, which *always* check the current 
checked-out connection is valid, using connection.ping() (MySQL specific, I 
think not all DBs support this). I'm still using my pool as of 0.3.1, to 
prevent those kind of errors.

I didn't find out why this occurs: having a test-case is very difficult. I'd 
also investigated the way the app access MySQL. IIRC, while using a socket, 
if a connection is timed-out, reaccessing the server 
automatically regenerate the connection (well, actually, I've not observed 
this behavior for all the mysql servers I use), without producing those 
errors. I have this kind of lines in MySQL logs when this occurs:

Connect [EMAIL PROTECTED] on dev
blablabla




Well, that's a lot of obscure observations... without a clean solution ! But 
maybe someone will have some ideas...



Cheers,

-- 
Sébastien LELONG
sebastien.lelong[at]sirloon.net


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