[sqlalchemy] Problems with merge relations

2008-01-30 Thread Paul-Michael Agapow

I'm using merge to push objects into a db. (Long story short: I have  
a set of objects that have to behave identically if they are  
persisted or not, and may be retrieved or sent to a set of databases.  
Hence the use of merge.)  However, merged objects appear object  
joined by a relation and backrefs twice. Is this a bug or an I making  
some subtle mistake?

A condensed demonstration - the names of the mapped objects and  
tables are unimportant, but a Biosequence has a one-to-many with a  
set of Annotations, established by a backref::

from sqlalchemy import *
from sqlalchemy.orm import *

metadata = MetaData()

class Biosequence (object):
pass

class Annotation (object):
pass

table_biosequences = Table ('biosequences', metadata,
Column ('identifier', Integer(), primary_key=True),
Column ('dummy', String(16)),
)

table_seqannotations = Table ('seqannotations', metadata,
Column ('identifier', Integer(), primary_key=True),
Column ('biosequence_id', Integer(), ForeignKey  
('biosequences.identifier')),
)

mapper (Annotation, table_seqannotations)
mapper (Biosequence, table_biosequences,
properties={
'annotations':relation (
Annotation,
backref='biosequence_ref',
lazy=False,
cascade=all, delete, delete-orphan,
),
},
)

engine = create_engine ('sqlite:///', convert_unicode=True,
# echo=True,
)
sessionfactory = sessionmaker (bind=engine, autoflush=False,  
transactional=False)
session = sessionfactory()
metadata.create_all (bind=engine, checkfirst=True)

# make an object with 3 'children'
bseq = Biosequence()
anns = [Annotation() for x in range (3)]
bseq.annotations = anns
print Original num of anns:, len (bseq.annotations)

# the merged copy has 6 children
merge_bseq = session.merge (bseq)
session.flush()
print Now num of anns still:, len (bseq.annotations)
print Ids:, [x.identifier for x in bseq.annotations]
print Merged copy num of anns:, len (merge_bseq.annotations)
print Ids:, [x.identifier for x in merge_bseq.annotations]

# as does the return!
results = session.query (Biosequence)
print Number of results, results.count()
returned_bseq = results.one()
print Returned num of anns:, len (returned_bseq.annotations)
print Ids:, [x.identifier for x in returned_bseq.annotations]

# make an new object with 3 children
bseq2 = Biosequence()
bseq2.annotations = [Annotation() for x in range (3)]
print New obj num of anns:, len (bseq.annotations)
session.save_or_update (bseq2)
session.flush()

# and it works as expected
results = session.query (Biosequence)
print Number of retreived objects, results.count()
returned_bseqs = results.all()
for item in returned_bseqs:
print Returned num of anns:, len (item.annotations)
print Ids:, [x.identifier for x in item.annotations]


Which returns::

Original num of anns: 3
Now num of anns still: 3
Ids: [None, None, None]
Merged copy num of anns: 6
Ids: [1, 1, 2, 2, 3, 3]
Number of results 1
Returned num of anns: 6
Ids: [1, 1, 2, 2, 3, 3]
New obj num of anns: 3
Number of retreived objects 2
Returned num of anns: 6
Ids: [1, 1, 2, 2, 3, 3]
Returned num of anns: 3
Ids: [4, 5, 6]

In summary: if an object is stored using 'save_or_update', when later  
retrieved, it has the correct number of related children. If merged,  
the returned merge copy has each child twice. If this object is  
retrieved later, it still has every child twice.  Looking at the db,  
the correct number of child rows is being stored and the relations  
are correct. It therefore looks like there's a problem in the session  
for merged objects.

Any pointers?

--
Dr Paul-Michael Agapow: VieDigitale / Inst. for Animal Health
[EMAIL PROTECTED] / [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] Re: odd question

2008-01-30 Thread Gaetan de Menten

On Jan 23, 2008 10:24 PM, Monty Taylor [EMAIL PROTECTED] wrote:

 This may or may not be elixir specific...

 If I have an auto-generated mapping table for a many-to-many
 relationship, is there a sensible way to add another column to it that's
 also has a foreign key relationship to a third table?

 Like, if I had this:

 Products
   id int
   name varchar

 ProductTypes
   id int
   name varchar

 Groups
   id int
   name varchar

 and then I defined a many to many between products and groups to get

 products_groups
   product_id
   group_id

 and I wanted to add producttype_id to that ...

You'll probably want to use the Association Object pattern, as described at:

http://www.sqlalchemy.org/docs/04/mappers.html#advdatamapping_relation_patterns_association

And possibly, the AssociationProxy plugin, at:

http://www.sqlalchemy.org/docs/04/plugins.html#plugins_associationproxy

This one can be used with Elixir just fine. You just need to import it
from SQLAlchemy:

from sqlalchemy.ext.associationproxy import AssociationProxy

-- 
Gaëtan de Menten
http://openhex.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: a way to share Session.mapper(SomeObject) across two scoped sessions?

2008-01-30 Thread Gaetan de Menten

On Jan 25, 2008 9:18 PM, Michael Bayer [EMAIL PROTECTED] wrote:


 On Jan 25, 2008, at 2:02 PM, Kumar McMillan wrote:

 
  On Jan 25, 2008 11:58 AM, Michael Bayer [EMAIL PROTECTED]
  wrote:

 
  The Session.mapper function is not worth it, in my opinion, it exists
  due to the sheer popularity of its previous incarnation,
  assign_mapper.  I much prefer keeping things explicit.
 
  I can understand that.  I am trying to get this working for an
  application that has its entire model declared in Elixir already.  I
  like how easy Elixir is and so I'd rather not abandon that layer.
  But, there is probably a way to configure Elixir for
  save_on_init=False, I will give it a go.

You can provide your own session (configured as you wish) to Elixir.
Only the default provided session (it's there for your convenience
only but you can perfectly not use it) use Session.mapper (and hence
the save_on_init thing).

 elixir shouldn't be dependent on Session.mapper, if it is, I would
 advise the elixir folks change that requirement ASAP.  in my view, at
 this point elixir should be for mapper configuration only; after that
 it should hand off to straight SQLAlchemy for normal runtime operation
 with any kind of Session configuration; else its just getting in the
 way.

As I said above, it is not anymore (it used to be dependent on
assign_mapper), but I changed it to support any kind of session (in
version 0.3 I think). The only thing, is that we still provide a
default session, which is based on Session.mapper, for convenience and
backward compatibility. Maybe we should state more prominently in the
Elixir doc that this is only a default session and that you can use
any session you like.

-- 
Gaëtan de Menten
http://openhex.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: a way to share Session.mapper(SomeObject) across two scoped sessions?

2008-01-30 Thread Jonathan LaCour

Gaetan de Menten wrote:

 The only thing, is that we still provide a default session,
 which is based on Session.mapper, for convenience and backward
 compatibility. Maybe we should state more prominently in the
 Elixir doc that this is only a default session and that you can
 use any session you like.

FYI, I think this should go in the advanced tutorial I referred to
this morning on the Elixir list...

--
Jonathan LaCour
http://cleverdevil.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: Problems with merge relations

2008-01-30 Thread Michael Bayer

its the backref.  as a temporary workaround you can remove it for  
merge() to function properly.  fix wil be out today and very possible  
release 0.4.3 will be today for this.


On Jan 30, 2008, at 6:14 AM, Paul-Michael Agapow wrote:

 from sqlalchemy import *
   from sqlalchemy.orm import *

   metadata = MetaData()

   class Biosequence (object):
   pass

   class Annotation (object):
   pass

   table_biosequences = Table ('biosequences', metadata,
   Column ('identifier', Integer(), primary_key=True),
   Column ('dummy', String(16)),
   )

   table_seqannotations = Table ('seqannotations', metadata,
   Column ('identifier', Integer(), primary_key=True),
   Column ('biosequence_id', Integer(), ForeignKey  
 ('biosequences.identifier')),
   )

   mapper (Annotation, table_seqannotations)
   mapper (Biosequence, table_biosequences,
   properties={
   'annotations':relation (
   Annotation,
   backref='biosequence_ref',
   lazy=False,
   cascade=all, delete, delete-orphan,
   ),
   },
   )

   engine = create_engine ('sqlite:///', convert_unicode=True,
   # echo=True,
   )
   sessionfactory = sessionmaker (bind=engine, autoflush=False,  
 transactional=False)
   session = sessionfactory()
   metadata.create_all (bind=engine, checkfirst=True)

   # make an object with 3 'children'
   bseq = Biosequence()
   anns = [Annotation() for x in range (3)]
   bseq.annotations = anns
   print Original num of anns:, len (bseq.annotations)

   # the merged copy has 6 children
   merge_bseq = session.merge (bseq)
   session.flush()
   print Now num of anns still:, len (bseq.annotations)
   print Ids:, [x.identifier for x in bseq.annotations]
   print Merged copy num of anns:, len (merge_bseq.annotations)
   print Ids:, [x.identifier for x in merge_bseq.annotations]

   # as does the return!
   results = session.query (Biosequence)
   print Number of results, results.count()
   returned_bseq = results.one()
   print Returned num of anns:, len (returned_bseq.annotations)
   print Ids:, [x.identifier for x in returned_bseq.annotations]

   # make an new object with 3 children
   bseq2 = Biosequence()
   bseq2.annotations = [Annotation() for x in range (3)]
   print New obj num of anns:, len (bseq.annotations)
   session.save_or_update (bseq2)
   session.flush()

   # and it works as expected
   results = session.query (Biosequence)
   print Number of retreived objects, results.count()
   returned_bseqs = results.all()
   for item in returned_bseqs:
   print Returned num of anns:, len (item.annotations)
   print Ids:, [x.identifier for x in item.annotations]




--~--~-~--~~~---~--~~
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: Problems with merge relations

2008-01-30 Thread Michael Bayer
OK this issue is actually limited to transient objects only; that  
is, if you had flushed your session before doing the merge() it would  
have worked.  The fix is in r4104.  Im considering putting out 0.4.3  
today as a mostly bugfix release but have not decided yet.

On Jan 30, 2008, at 6:14 AM, Paul-Michael Agapow wrote:


 I'm using merge to push objects into a db. (Long story short: I have  
 a set of objects that have to behave identically if they are  
 persisted or not, and may be retrieved or sent to a set of  
 databases. Hence the use of merge.)  However, merged objects appear  
 object joined by a relation and backrefs twice. Is this a bug or an  
 I making some subtle mistake?

 A condensed demonstration - the names of the mapped objects and  
 tables are unimportant, but a Biosequence has a one-to-many with a  
 set of Annotations, established by a backref::

   from sqlalchemy import *
   from sqlalchemy.orm import *

   metadata = MetaData()

   class Biosequence (object):
   pass

   class Annotation (object):
   pass

   table_biosequences = Table ('biosequences', metadata,
   Column ('identifier', Integer(), primary_key=True),
   Column ('dummy', String(16)),
   )

   table_seqannotations = Table ('seqannotations', metadata,
   Column ('identifier', Integer(), primary_key=True),
   Column ('biosequence_id', Integer(), ForeignKey  
 ('biosequences.identifier')),
   )

   mapper (Annotation, table_seqannotations)
   mapper (Biosequence, table_biosequences,
   properties={
   'annotations':relation (
   Annotation,
   backref='biosequence_ref',
   lazy=False,
   cascade=all, delete, delete-orphan,
   ),
   },
   )

   engine = create_engine ('sqlite:///', convert_unicode=True,
   # echo=True,
   )
   sessionfactory = sessionmaker (bind=engine, autoflush=False,  
 transactional=False)
   session = sessionfactory()
   metadata.create_all (bind=engine, checkfirst=True)

   # make an object with 3 'children'
   bseq = Biosequence()
   anns = [Annotation() for x in range (3)]
   bseq.annotations = anns
   print Original num of anns:, len (bseq.annotations)

   # the merged copy has 6 children
   merge_bseq = session.merge (bseq)
   session.flush()
   print Now num of anns still:, len (bseq.annotations)
   print Ids:, [x.identifier for x in bseq.annotations]
   print Merged copy num of anns:, len (merge_bseq.annotations)
   print Ids:, [x.identifier for x in merge_bseq.annotations]

   # as does the return!
   results = session.query (Biosequence)
   print Number of results, results.count()
   returned_bseq = results.one()
   print Returned num of anns:, len (returned_bseq.annotations)
   print Ids:, [x.identifier for x in returned_bseq.annotations]

   # make an new object with 3 children
   bseq2 = Biosequence()
   bseq2.annotations = [Annotation() for x in range (3)]
   print New obj num of anns:, len (bseq.annotations)
   session.save_or_update (bseq2)
   session.flush()

   # and it works as expected
   results = session.query (Biosequence)
   print Number of retreived objects, results.count()
   returned_bseqs = results.all()
   for item in returned_bseqs:
   print Returned num of anns:, len (item.annotations)
   print Ids:, [x.identifier for x in item.annotations]


 Which returns::

   Original num of anns: 3
   Now num of anns still: 3
   Ids: [None, None, None]
   Merged copy num of anns: 6
   Ids: [1, 1, 2, 2, 3, 3]
   Number of results 1
   Returned num of anns: 6
   Ids: [1, 1, 2, 2, 3, 3]
   New obj num of anns: 3
   Number of retreived objects 2
   Returned num of anns: 6
   Ids: [1, 1, 2, 2, 3, 3]
   Returned num of anns: 3
   Ids: [4, 5, 6]

 In summary: if an object is stored using 'save_or_update', when  
 later retrieved, it has the correct number of related children. If  
 merged, the returned merge copy has each child twice. If this object  
 is retrieved later, it still has every child twice.  Looking at the  
 db, the correct number of child rows is being stored and the  
 relations are correct. It therefore looks like there's a problem in  
 the session for merged objects.

 Any pointers?

 --
 Dr Paul-Michael Agapow: VieDigitale / Inst. for Animal Health
 [EMAIL PROTECTED] / [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 

[sqlalchemy] Re: Problems with merge relations

2008-01-30 Thread Michael Bayer


On Jan 30, 2008, at 12:39 PM, Michael Bayer wrote:

 OK this issue is actually limited to transient objects only; that  
 is, if you had flushed your session before doing the merge() it  
 would have worked.  The fix is in r4104.  Im considering putting out  
 0.4.3 today as a mostly bugfix release but have not decided yet.


to clarify, i meant, if in your test case you were merge()ing  
Biosequence/Annotation objects which were already persistent from a  
previous flush(), that alleviates the bug. 
  

--~--~-~--~~~---~--~~
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] Questions on MapperExtension

2008-01-30 Thread Ross

Hello,

I have recently converted a Pylons app from SQLObject to SQLAlchemy
0.3.10.  Conversion went quite well.

I need to serialize access to some of my objects, so I've looked into
extending MapperExtension as described at [1] to add a mutex on load.

First, I define an extension and instantiate it:

from sqlalchemy.orm import MapperExtension
import mutex

class MutexExtension(MapperExtension):
def create_instance(self, mapper, selectcontext, row, class_):
self.mutex = mutex.mutex()
return None

mutexext = MutexExtension()
---


My mapper setup looks like this:

switch_mapper = mapper (Switch, switch_table,
extension=[mutexext.mutexext, sac.ext],
 
properties={'ports':sqla.relation(SwitchPort)})


When I try to fetch objects from the database, I get a exception
setting
self.entity_name:


Module sqlalchemy.orm.mapper:1485 in _instance
  instance = self._create_instance(context.session)
else:
instance._entity_name = self.entity_name
if self.__should_log_debug:
self.__log_debug(_instance(): created new
instance %s identity %s % (mapperutil.instance_str(instance),
%str(identitykey)))
instance._entity_name = self.entity_name
exceptions.AttributeError: 'NoneType' object has no attribute
'_entity_name'


What did I do wrong?

Thanks,
Ross




[1] 
http://www.sqlalchemy.org/docs/03/adv_datamapping.html#advdatamapping_extending

--~--~-~--~~~---~--~~
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: Questions on MapperExtension

2008-01-30 Thread Michael Bayer

sorry, the docstring is wrong.  create_instance() should return  
EXT_CONTINUE if it would like to bypass creating the instance itself.   
However, self here is the MapperExtension instance, not the mapped  
instance.   the method is called before anything is created.

if you want to populate an attribute on a newly loaded instance but  
not create it, you're better off using populate_instance().  return  
EXT_CONTINUE from that method as well.

class MyExt(MapperExtension):
def populate_instance(self, mapper, selectcontext, row, instance,  
**flags):
if not hasattr(instance, 'mutex'):
instance.mutex = mutex()
return EXT CONTINUE

the hasattr() is assuming you dont want to replace the mutex in the  
case of a session.refresh() or similar.

On Jan 30, 2008, at 1:36 PM, Ross wrote:


 Hello,

 I have recently converted a Pylons app from SQLObject to SQLAlchemy
 0.3.10.  Conversion went quite well.

 I need to serialize access to some of my objects, so I've looked into
 extending MapperExtension as described at [1] to add a mutex on load.

 First, I define an extension and instantiate it:
 
 from sqlalchemy.orm import MapperExtension
 import mutex

 class MutexExtension(MapperExtension):
def create_instance(self, mapper, selectcontext, row, class_):
self.mutex = mutex.mutex()
return None

 mutexext = MutexExtension()
 ---


 My mapper setup looks like this:

 switch_mapper = mapper (Switch, switch_table,
 extension=[mutexext.mutexext, sac.ext],

 properties={'ports':sqla.relation(SwitchPort)})


 When I try to fetch objects from the database, I get a exception
 setting
 self.entity_name:


 Module sqlalchemy.orm.mapper:1485 in _instance
   instance = self._create_instance(context.session)
else:
instance._entity_name = self.entity_name
if self.__should_log_debug:
self.__log_debug(_instance(): created new
 instance %s identity %s % (mapperutil.instance_str(instance),
 %str(identitykey)))
 instance._entity_name = self.entity_name
 exceptions.AttributeError: 'NoneType' object has no attribute
 '_entity_name'


 What did I do wrong?

 Thanks,
 Ross




 [1] 
 http://www.sqlalchemy.org/docs/03/adv_datamapping.html#advdatamapping_extending

 


--~--~-~--~~~---~--~~
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: DPAPI Error

2008-01-30 Thread Michael Bayer


On Jan 30, 2008, at 2:10 PM, jon wrote:


 Thanks for getting back to me and apologies for the stacktrace
 barf ;-)

 One thing...I have the following line in my environment.py:

 config['pylons.g'].sa_engine = engine_from_config(config,
 'sqlalchemy.', convert_unicode=True, pool_size=1, max_overflow=3)

 I can turn on/off the convert_unicode option and I still get the same
 error. I spoke with one of our DBAs and he said the results of
 roleseq.nextval is a number. SA is looking for a String here or None,
 according to the exception error:

 exceptions.TypeError: expecting None or a string

 Sooo...is this still an SA thing and if so what do you suggest as a
 workaround?


jon -

none of that has anything to do with the error message here.  You need  
to grep thorugh your code for the specific string :   
Sequence(u'roleseq'), or something equivalent.  I know its there  
because the Oracle dialect does not invent or reflect any sequence  
names.  You need to make that sequence name into a regular string  
object; as above you'd take out the u inside the parenthesis.

let me know when you find it as I'd like to confirm this is the source  
of the issuethanks !

- mike


--~--~-~--~~~---~--~~
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: Questions on MapperExtension

2008-01-30 Thread jason kirtland

On 0.3.x, use EXT_PASS rather than EXT_CONTINUE.

Michael Bayer wrote:
 sorry, the docstring is wrong.  create_instance() should return  
 EXT_CONTINUE if it would like to bypass creating the instance itself.   
 However, self here is the MapperExtension instance, not the mapped  
 instance.   the method is called before anything is created.
 
 if you want to populate an attribute on a newly loaded instance but  
 not create it, you're better off using populate_instance().  return  
 EXT_CONTINUE from that method as well.
 
 class MyExt(MapperExtension):
   def populate_instance(self, mapper, selectcontext, row, instance,  
 **flags):
   if not hasattr(instance, 'mutex'):
   instance.mutex = mutex()
   return EXT CONTINUE
 
 the hasattr() is assuming you dont want to replace the mutex in the  
 case of a session.refresh() or similar.
 
 On Jan 30, 2008, at 1:36 PM, Ross wrote:
 
 Hello,

 I have recently converted a Pylons app from SQLObject to SQLAlchemy
 0.3.10.  Conversion went quite well.

 I need to serialize access to some of my objects, so I've looked into
 extending MapperExtension as described at [1] to add a mutex on load.

 First, I define an extension and instantiate it:
 
 from sqlalchemy.orm import MapperExtension
 import mutex

 class MutexExtension(MapperExtension):
def create_instance(self, mapper, selectcontext, row, class_):
self.mutex = mutex.mutex()
return None

 mutexext = MutexExtension()
 ---


 My mapper setup looks like this:

 switch_mapper = mapper (Switch, switch_table,
 extension=[mutexext.mutexext, sac.ext],

 properties={'ports':sqla.relation(SwitchPort)})


 When I try to fetch objects from the database, I get a exception
 setting
 self.entity_name:


 Module sqlalchemy.orm.mapper:1485 in _instance
   instance = self._create_instance(context.session)
else:
instance._entity_name = self.entity_name
if self.__should_log_debug:
self.__log_debug(_instance(): created new
 instance %s identity %s % (mapperutil.instance_str(instance),
 %str(identitykey)))
 instance._entity_name = self.entity_name
 exceptions.AttributeError: 'NoneType' object has no attribute
 '_entity_name'


 What did I do wrong?

 Thanks,
 Ross




 [1] 
 http://www.sqlalchemy.org/docs/03/adv_datamapping.html#advdatamapping_extending

 
 
  


--~--~-~--~~~---~--~~
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: Questions on MapperExtension

2008-01-30 Thread Michael Bayer

oh, 0.3.  well theres another question.  If you just converted from  
SQLObject, why to SA 0.3 ?  0.4 is the currently supported version and  
is also vastly superior to 0.3.

On Jan 30, 2008, at 2:40 PM, jason kirtland wrote:


 On 0.3.x, use EXT_PASS rather than EXT_CONTINUE.

 Michael Bayer wrote:
 sorry, the docstring is wrong.  create_instance() should return
 EXT_CONTINUE if it would like to bypass creating the instance itself.
 However, self here is the MapperExtension instance, not the mapped
 instance.   the method is called before anything is created.

 if you want to populate an attribute on a newly loaded instance but
 not create it, you're better off using populate_instance().  return
 EXT_CONTINUE from that method as well.

 class MyExt(MapperExtension):
  def populate_instance(self, mapper, selectcontext, row, instance,
 **flags):
  if not hasattr(instance, 'mutex'):
  instance.mutex = mutex()
  return EXT CONTINUE

 the hasattr() is assuming you dont want to replace the mutex in the
 case of a session.refresh() or similar.

 On Jan 30, 2008, at 1:36 PM, Ross wrote:

 Hello,

 I have recently converted a Pylons app from SQLObject to SQLAlchemy
 0.3.10.  Conversion went quite well.

 I need to serialize access to some of my objects, so I've looked  
 into
 extending MapperExtension as described at [1] to add a mutex on  
 load.

 First, I define an extension and instantiate it:
 
 from sqlalchemy.orm import MapperExtension
 import mutex

 class MutexExtension(MapperExtension):
   def create_instance(self, mapper, selectcontext, row, class_):
   self.mutex = mutex.mutex()
   return None

 mutexext = MutexExtension()
 ---


 My mapper setup looks like this:

 switch_mapper = mapper (Switch, switch_table,
 extension=[mutexext.mutexext, sac.ext],

 properties={'ports':sqla.relation(SwitchPort)})


 When I try to fetch objects from the database, I get a exception
 setting
 self.entity_name:


 Module sqlalchemy.orm.mapper:1485 in _instance
   instance =  
 self._create_instance(context.session)
   else:
   instance._entity_name = self.entity_name
   if self.__should_log_debug:
   self.__log_debug(_instance(): created new
 instance %s identity %s % (mapperutil.instance_str(instance),
 %str(identitykey)))
 instance._entity_name = self.entity_name
 exceptions.AttributeError: 'NoneType' object has no attribute
 '_entity_name'


 What did I do wrong?

 Thanks,
 Ross




 [1] 
 http://www.sqlalchemy.org/docs/03/adv_datamapping.html#advdatamapping_extending






 


--~--~-~--~~~---~--~~
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: DPAPI Error

2008-01-30 Thread jon

Hi Mike,

Thanks for your patience...here is the entry I have for that table in
model/__init__.py

role_table = Table('role', metadata,
   Column('roleseq', Integer, Sequence('roleseq'),
primary_key=True),

I know that I specifically didn't set things up for Unicode in this
app either...this file is the only one that contains the Sequence
declaration.

Thanks,

Jon

On Jan 30, 11:34 am, Michael Bayer [EMAIL PROTECTED] wrote:
 On Jan 30, 2008, at 2:10 PM, jon wrote:





  Thanks for getting back to me and apologies for the stacktrace
  barf ;-)

  One thing...I have the following line in my environment.py:

  config['pylons.g'].sa_engine = engine_from_config(config,
  'sqlalchemy.', convert_unicode=True, pool_size=1, max_overflow=3)

  I can turn on/off the convert_unicode option and I still get the same
  error. I spoke with one of our DBAs and he said the results of
  roleseq.nextval is a number. SA is looking for a String here or None,
  according to the exception error:

  exceptions.TypeError: expecting None or a string

  Sooo...is this still an SA thing and if so what do you suggest as a
  workaround?

 jon -

 none of that has anything to do with the error message here.  You need
 to grep thorugh your code for the specific string :
 Sequence(u'roleseq'), or something equivalent.  I know its there
 because the Oracle dialect does not invent or reflect any sequence
 names.  You need to make that sequence name into a regular string
 object; as above you'd take out the u inside the parenthesis.

 let me know when you find it as I'd like to confirm this is the source
 of the issuethanks !

 - mike
--~--~-~--~~~---~--~~
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: Questions on MapperExtension

2008-01-30 Thread Ross

Thanks - populate_instance does exactly what I was looking for!

I went to SA 0.3 with SAContext because I was familiar with it.
Porting from SQLObject was straightforward, but a fairly large task.
From reading at pylonshq, converting 0.3 to 0.4 seemed to be much
easier than converting SQLObject to SQLAlchemy.  So I decided I'd
tackle them as two phases so I could keep my code working for as long
as possible.

I know I'm going to want to upgrade at some point because I'll make
good use of the self-referential updates.

Thanks for the tips!

On Jan 30, 2:48 pm, Michael Bayer [EMAIL PROTECTED] wrote:
 oh, 0.3.  well theres another question.  If you just converted from
 SQLObject, why to SA 0.3 ?  0.4 is the currently supported version and
 is also vastly superior to 0.3.

 On Jan 30, 2008, at 2:40 PM, jason kirtland wrote:



  On 0.3.x, use EXT_PASS rather than EXT_CONTINUE.

  Michael Bayer wrote:
  sorry, the docstring is wrong.  create_instance() should return
  EXT_CONTINUE if it would like to bypass creating the instance itself.
  However, self here is the MapperExtension instance, not the mapped
  instance.   the method is called before anything is created.

  if you want to populate an attribute on a newly loaded instance but
  not create it, you're better off using populate_instance().  return
  EXT_CONTINUE from that method as well.

  class MyExt(MapperExtension):
 def populate_instance(self, mapper, selectcontext, row, instance,
  **flags):
 if not hasattr(instance, 'mutex'):
 instance.mutex = mutex()
 return EXT CONTINUE

  the hasattr() is assuming you dont want to replace the mutex in the
  case of a session.refresh() or similar.

  On Jan 30, 2008, at 1:36 PM, Ross wrote:

  Hello,

  I have recently converted a Pylons app from SQLObject to SQLAlchemy
  0.3.10.  Conversion went quite well.

  I need to serialize access to some of my objects, so I've looked
  into
  extending MapperExtension as described at [1] to add a mutex on
  load.

  First, I define an extension and instantiate it:
  
  from sqlalchemy.orm import MapperExtension
  import mutex

  class MutexExtension(MapperExtension):
def create_instance(self, mapper, selectcontext, row, class_):
self.mutex = mutex.mutex()
return None

  mutexext = MutexExtension()
  ---

  My mapper setup looks like this:

  switch_mapper = mapper (Switch, switch_table,
  extension=[mutexext.mutexext, sac.ext],

  properties={'ports':sqla.relation(SwitchPort)})

  When I try to fetch objects from the database, I get a exception
  setting
  self.entity_name:

  Module sqlalchemy.orm.mapper:1485 in _instance
instance =
  self._create_instance(context.session)
else:
instance._entity_name = self.entity_name
if self.__should_log_debug:
self.__log_debug(_instance(): created new
  instance %s identity %s % (mapperutil.instance_str(instance),
  %str(identitykey)))
  instance._entity_name = self.entity_name
  exceptions.AttributeError: 'NoneType' object has no attribute
  '_entity_name'

  What did I do wrong?

  Thanks,
  Ross

  [1]http://www.sqlalchemy.org/docs/03/adv_datamapping.html#advdatamapping...
--~--~-~--~~~---~--~~
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: DPAPI Error

2008-01-30 Thread Michael Bayer

hey jon -

OK, I found an issue that is very likely to be what you are  
experiencing;  easy to fix as always but unless you can run on SVN  
trunk r4106, you'll have to workaround it.

There may be a schema identifier somewhere in your app that contains  
the identifier 'roleseq' as a unicode string, which is getting cached  
as a u''.

So if you can't hunt that down (which you shouldn't have to), you can  
force it to cache the non-unicode string for now if you do this to  
your engine as early as possible (i.e. before the incorrect value gets  
cached):

engine.dialect.identifier_preparer.format_sequence(Sequence('roleseq'))

hope thats the issue.

- mike

On Jan 30, 2008, at 3:14 PM, jon wrote:


 Hi Mike,

 Thanks for your patience...here is the entry I have for that table in
 model/__init__.py

 role_table = Table('role', metadata,
   Column('roleseq', Integer, Sequence('roleseq'),
 primary_key=True),

 I know that I specifically didn't set things up for Unicode in this
 app either...this file is the only one that contains the Sequence
 declaration.

 Thanks,

 Jon

 On Jan 30, 11:34 am, Michael Bayer [EMAIL PROTECTED] wrote:
 On Jan 30, 2008, at 2:10 PM, jon wrote:





 Thanks for getting back to me and apologies for the stacktrace
 barf ;-)

 One thing...I have the following line in my environment.py:

 config['pylons.g'].sa_engine = engine_from_config(config,
 'sqlalchemy.', convert_unicode=True, pool_size=1, max_overflow=3)

 I can turn on/off the convert_unicode option and I still get the  
 same
 error. I spoke with one of our DBAs and he said the results of
 roleseq.nextval is a number. SA is looking for a String here or  
 None,
 according to the exception error:

 exceptions.TypeError: expecting None or a string

 Sooo...is this still an SA thing and if so what do you suggest as a
 workaround?

 jon -

 none of that has anything to do with the error message here.  You  
 need
 to grep thorugh your code for the specific string :
 Sequence(u'roleseq'), or something equivalent.  I know its there
 because the Oracle dialect does not invent or reflect any sequence
 names.  You need to make that sequence name into a regular string
 object; as above you'd take out the u inside the parenthesis.

 let me know when you find it as I'd like to confirm this is the  
 source
 of the issuethanks !

 - mike
 


--~--~-~--~~~---~--~~
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: select.count() vs MSSQL

2008-01-30 Thread Rick Morrison
...or is  select.alias().count().scalar()the standard way to do this?

On Jan 30, 2008 7:29 PM, Rick Morrison [EMAIL PROTECTED] wrote:

 Just noticed that select.count() doesn't work on MSSQL. The implementation
 wraps the select() in an outer query; MSSQL requires an alias for the inner
 table when you do this.

 What's the visit_xxx function that we need to catch in the db module to
 ensure the inner query is aliasized ?


--~--~-~--~~~---~--~~
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: select.count() vs MSSQL

2008-01-30 Thread Michael Bayer

youd have to override visit_select() and pick up on  
compiler.is_subquery().  you could then do some tricks similar to what  
oracle.py does in visit_select() to create a wrapping layer.

also i noticed the usage of a kwarg 'mssql_aliased' which seems to be  
referenced nowhere.

On Jan 30, 2008, at 7:29 PM, Rick Morrison wrote:

 Just noticed that select.count() doesn't work on MSSQL. The  
 implementation wraps the select() in an outer query; MSSQL requires  
 an alias for the inner table when you do this.

 What's the visit_xxx function that we need to catch in the db module  
 to ensure the inner query is aliasized ?

 


--~--~-~--~~~---~--~~
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: SQLAlchemy advanced tutorial at PyCon

2008-01-30 Thread Tim Lesher

On Jan 28, 4:23 pm, Jonathan Ellis [EMAIL PROTECTED] wrote:
 What would you like to see covered in an advanced SQLAlchemy session?

Something on association objects would be good.

--~--~-~--~~~---~--~~
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: select.count() vs MSSQL

2008-01-30 Thread Rick Morrison
Thanks Mike,

I've got my local visit_select() a bit munged-up right now with an
implementation of OFFSET, so I'm going to wait a bit on this. In the
meantime, a follow-up:

Not every MSSQL subquery needs to be aliased, only when the subquery is used
as a derived table, as the SA implementation of select.count() does. Is it
safe to alias all subqueries (for example, those used by EXISTS  etc.),

or, is there some flag that select.count() sets that the aliasing code could
check,

or would it make more sense to have select.count() check a Dialect-specific
flag like 'derived_tables_require_alias' and do the aliasing there?

 also i noticed the usage of a kwarg 'mssql_aliased' which seems to be
 referenced nowhere.

Looks to me as if the kwarg is being used as a flag to avoid recursion into
the visit_table() method. It may not be needed anymore, I'm not up on all
the whens and hows of how the visitor pattern threads though all its calls
for the Dialects.

--~--~-~--~~~---~--~~
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: select.count() vs MSSQL

2008-01-30 Thread Michael Bayer


On Jan 30, 2008, at 10:52 PM, Rick Morrison wrote:

 Thanks Mike,

 I've got my local visit_select() a bit munged-up right now with an  
 implementation of OFFSET, so I'm going to wait a bit on this. In the  
 meantime, a follow-up:

 Not every MSSQL subquery needs to be aliased, only when the subquery  
 is used as a derived table, as the SA implementation of  
 select.count() does. Is it safe to alias all subqueries (for  
 example, those used by EXISTS  etc.),

 or, is there some flag that select.count() sets that the aliasing  
 code could check,

 or would it make more sense to have select.count() check a Dialect- 
 specific flag like 'derived_tables_require_alias' and do the  
 aliasing there?

you can in fact alias whatever select you want, i think.   
select.count() doesn't produce any kind of special construct that  
could be detected in the compiler.   there is the notion that  
subqueries which are used as scalar subqueries, i.e. for EXISTS, are  
wrapped in a _ScalarSelect wrapper (i.e. select.as_scalar()), but some  
more tracking would have to be added to the compiler to figure out  
that a particular SELECT is wrapped in a scalar (you could also do  
that tracking in the mssql compiler too by overriding visit_grouping()).



  also i noticed the usage of a kwarg 'mssql_aliased' which seems to  
 be
  referenced nowhere.

 Looks to me as if the kwarg is being used as a flag to avoid  
 recursion into the visit_table() method. It may not be needed  
 anymore, I'm not up on all the whens and hows of how the visitor  
 pattern threads though all its calls for the Dialects.

yes its referenced there, somehow my text editor missed it earlier.

--~--~-~--~~~---~--~~
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: select.count() vs MSSQL

2008-01-30 Thread Michael Bayer


On Jan 30, 2008, at 11:08 PM, Michael Bayer wrote:



 you can in fact alias whatever select you want, i think.
 select.count() doesn't produce any kind of special construct that
 could be detected in the compiler.   there is the notion that
 subqueries which are used as scalar subqueries, i.e. for EXISTS, are
 wrapped in a _ScalarSelect wrapper (i.e. select.as_scalar()), but some
 more tracking would have to be added to the compiler to figure out
 that a particular SELECT is wrapped in a scalar (you could also do
 that tracking in the mssql compiler too by overriding  
 visit_grouping()).

like this:

Index: lib/sqlalchemy/databases/mssql.py
===
--- lib/sqlalchemy/databases/mssql.py   (revision 4108)
+++ lib/sqlalchemy/databases/mssql.py   (working copy)
@@ -896,6 +896,9 @@
  else:
  return None

+def visit_select(self, select, within_grouping=False, **kwargs):
+return super(MSSQLCompiler, self).visit_select(select,  
**kwargs)
+
  def visit_table(self, table, mssql_aliased=False, **kwargs):
  if mssql_aliased:
  return super(MSSQLCompiler, self).visit_table(table,  
**kwargs)
Index: lib/sqlalchemy/sql/compiler.py
===
--- lib/sqlalchemy/sql/compiler.py  (revision 4108)
+++ lib/sqlalchemy/sql/compiler.py  (working copy)
@@ -230,7 +230,7 @@
  return 

  def visit_grouping(self, grouping, **kwargs):
-return ( + self.process(grouping.elem) + )
+return ( + self.process(grouping.elem,  
within_grouping=True) + )

  def visit_label(self, label, result_map=None):
  labelname = self._truncated_identifier(colident, label.name)




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