[sqlalchemy] Re: concurrent versions of SA

2009-09-22 Thread werner

Peter,

PD wrote:
 Hi,
 please can someone help me with this (maybe simple solution): Is it
 possible to install two (or more) versions of SA in one Python
 environment and import specific version? E.g. when migrating from old
 version.
   
If you installed using easy_setup then you can do:

import pkg_resources
pkg_resources.require(sqlalchemy) # get latest version

or:
pkg_resources.require(sqlalchemy==0.4.3) # use a specific version

Werner



--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: concurrent versions of SA

2009-09-22 Thread werner

werner wrote:
 Peter,

 PD wrote:
   
 Hi,
 please can someone help me with this (maybe simple solution): Is it
 possible to install two (or more) versions of SA in one Python
 environment and import specific version? E.g. when migrating from old
 version.
   
 
 If you installed using easy_setup then you can do:
   
Meant easy_install - haven't had my tea yet:) 
  
 import pkg_resources
 pkg_resources.require(sqlalchemy) # get latest version

 or:
 pkg_resources.require(sqlalchemy==0.4.3) # use a specific version

 Werner



 

   




--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Beginner inheritance question

2009-09-22 Thread Iwan

Hi there,

this is perhaps a stupid question, but we can't get it figured out
from the docs on inheritance...

Is it possible in sqlalchemy to have a hierarchy of classes of which
only the root class in the hierarchy is mapped to the database at
all.  (So the subclasses do not have any persisted attributes of their
own, and are all in essence mapped to the same table.)

I suppose single inheritance would work here, but I'd like to keep
open the option of one day adding one special subclass which DOES in
fact want to persist extra attributes - this time using joined table
inheritance.

Is something (or a mix) like this possible?

Thanks
- i
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: concurrent versions of SA

2009-09-22 Thread werner

PD wrote:
 Hi,
 please can someone help me with this (maybe simple solution): Is it
 possible to install two (or more) versions of SA in one Python
 environment and import specific version? E.g. when migrating from old
 version.
   
You might also want to look into:
http://pypi.python.org/pypi/virtualenv

Projects like turbogears recommend it, I haven't got around to try it 
out yet.

Werner



--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] How to replace a property in a declarative way

2009-09-22 Thread Kees van den Broek

Hi,

I simplified my problem to a small example (see model below).
A Product has several Tags attached. A beachball is green, blue, round
and big:

p=Product()
p.name = Beachball
p.tags = [greenTag, blueTag, roundTag, bigTag]
DBSession.save(p)

Often I just want to see the color-related tags, not the other tags.
Therefore, I group all color tags in a Collection:
c=Collection()
c.name = Colors
c.tags = [greenTag, blueTag, brownTag]
DBSession.save(c)

See what colors are attached to the product:
 p = DBSession.query(Product).filter(Product.name == Beachball).first()
 p.colors
[Tag: id=1706, name=green, Tag: id=1707, name=blue]

Here's my issue. To get the colors, I defined a property, which
results in an extra query.
I want the color Tags to be fetched in the same query when I fetch the
Product itself (optionally with lazy loading)
I guess I need another relation() definition with a Collection join
and Collection name filter applied.
I couldn't come up with the code to get me there. How should I tackle
this?

Cheers,
Kees


The model:

product_tag_table = Table('product_tag', metadata,
Column('product_id', Integer, ForeignKey('product.id',
onupdate=CASCADE, ondelete=CASCADE)),
Column('tag_id', Integer, ForeignKey('tag.id',
onupdate=CASCADE, ondelete=CASCADE))
)

tag_collection_table = Table('tag_collection', metadata,
Column('tag_id', Integer, ForeignKey('tag.id',
onupdate=CASCADE, ondelete=CASCADE)),
Column('collection_id', Integer, ForeignKey('collection.id',
onupdate=CASCADE, ondelete=CASCADE))
)

class Product(DeclarativeBase):
__tablename__ = 'product'
id = Column(Integer, autoincrement=True, primary_key=True)
name = Column(Unicode(255), nullable=False)
tags = relation('Tag', secondary=product_tag_table,
backref='products')

# XXX: REPLACE THIS PROPERTY WITH A FILTERED RELATION?
def _get_colors(self):
color_tags=DBSession.query(Collection).\
filter(Collection.name==Colors).first().tags
return filter(lambda tag: tag in self.tags, color_tags)
colors = property(_get_colors)

class Tag(DeclarativeBase):
__tablename__ = 'tag'
id = Column(Integer, autoincrement=True, primary_key=True)
name = Column(Unicode(255), unique=True, nullable=False)

class Collection(DeclarativeBase):
__tablename__ = 'collection'
id = Column(Integer, autoincrement=True, primary_key=True)
name = Column(Unicode(255), unique=True, nullable=False)
tags = relation('Tag', secondary=tag_collection_table,
backref='collections')


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] object serializer

2009-09-22 Thread Julien Cigar

Hello,

I'm busy to make a kind of mapper exporter/serializer. My goal is to
be able to serialize (in JSON, XML, ...) any Mapper object (including
relations, etc)

At the moment I've the following code (not finished at all) :
http://www.pastie.org/625787

As you can see I'm iterating over mapper.iterate_properties list (line
60), and before I goes any further I wondered if it's the right way to
do it ? (I would like to have all the properties, including column type,
etc)

Another question: I see that the property columns of an
sqlalchemy.orm.properties.ColumnProperty instance is a list and I
wondered in which cases the list can contains more than one item ?

Thanks,
Julien

-- 
Julien Cigar
Belgian Biodiversity Platform
http://www.biodiversity.be
Université Libre de Bruxelles (ULB)
Campus de la Plaine CP 257
Bâtiment NO, Bureau 4 N4 115C (Niveau 4)
Boulevard du Triomphe, entrée ULB 2
B-1050 Bruxelles
Mail: jci...@ulb.ac.be
@biobel: http://biobel.biodiversity.be/person/show/471
Tel : 02 650 57 52

No trees were killed in the creation of this message.
However, many electrons were terribly inconvenienced.


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: How to replace a property in a declarative way

2009-09-22 Thread Conor

On Sep 22, 5:57 am, Kees van den Broek kees...@gmail.com wrote:
 Hi,

 I simplified my problem to a small example (see model below).
 A Product has several Tags attached. A beachball is green, blue, round
 and big:

 p=Product()
 p.name = Beachball
 p.tags = [greenTag, blueTag, roundTag, bigTag]
 DBSession.save(p)

 Often I just want to see the color-related tags, not the other tags.
 Therefore, I group all color tags in a Collection:
 c=Collection()
 c.name = Colors
 c.tags = [greenTag, blueTag, brownTag]
 DBSession.save(c)

 See what colors are attached to the product: p = 
 DBSession.query(Product).filter(Product.name == Beachball).first()
  p.colors

 [Tag: id=1706, name=green, Tag: id=1707, name=blue]

 Here's my issue. To get the colors, I defined a property, which
 results in an extra query.
 I want the color Tags to be fetched in the same query when I fetch the
 Product itself (optionally with lazy loading)
 I guess I need another relation() definition with a Collection join
 and Collection name filter applied.
 I couldn't come up with the code to get me there. How should I tackle
 this?


 Cheers,
 Kees

 The model:

 product_tag_table = Table('product_tag', metadata,
     Column('product_id', Integer, ForeignKey('product.id',
         onupdate=CASCADE, ondelete=CASCADE)),
     Column('tag_id', Integer, ForeignKey('tag.id',
         onupdate=CASCADE, ondelete=CASCADE))
 )

 tag_collection_table = Table('tag_collection', metadata,
     Column('tag_id', Integer, ForeignKey('tag.id',
         onupdate=CASCADE, ondelete=CASCADE)),
     Column('collection_id', Integer, ForeignKey('collection.id',
         onupdate=CASCADE, ondelete=CASCADE))
 )

 class Product(DeclarativeBase):
     __tablename__ = 'product'
     id = Column(Integer, autoincrement=True, primary_key=True)
     name = Column(Unicode(255), nullable=False)
     tags = relation('Tag', secondary=product_tag_table,
 backref='products')

     # XXX: REPLACE THIS PROPERTY WITH A FILTERED RELATION?
     def _get_colors(self):
         color_tags=DBSession.query(Collection).\
                 filter(Collection.name==Colors).first().tags
         return filter(lambda tag: tag in self.tags, color_tags)
     colors = property(_get_colors)

 class Tag(DeclarativeBase):
     __tablename__ = 'tag'
     id = Column(Integer, autoincrement=True, primary_key=True)
     name = Column(Unicode(255), unique=True, nullable=False)

 class Collection(DeclarativeBase):
     __tablename__ = 'collection'
     id = Column(Integer, autoincrement=True, primary_key=True)
     name = Column(Unicode(255), unique=True, nullable=False)
     tags = relation('Tag', secondary=tag_collection_table,
 backref='collections')
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: How to replace a property in a declarative way

2009-09-22 Thread Conor

On Sep 22, 9:39 am, Conor conor.edward.da...@gmail.com wrote:
 On Sep 22, 5:57 am, Kees van den Broek kees...@gmail.com wrote:

  Hi,

  I simplified my problem to a small example (see model below).
  A Product has several Tags attached. A beachball is green, blue, round
  and big:

  p=Product()
  p.name = Beachball
  p.tags = [greenTag, blueTag, roundTag, bigTag]
  DBSession.save(p)

  Often I just want to see the color-related tags, not the other tags.
  Therefore, I group all color tags in a Collection:
  c=Collection()
  c.name = Colors
  c.tags = [greenTag, blueTag, brownTag]
  DBSession.save(c)

  See what colors are attached to the product: p = 
  DBSession.query(Product).filter(Product.name == Beachball).first()
   p.colors

  [Tag: id=1706, name=green, Tag: id=1707, name=blue]

  Here's my issue. To get the colors, I defined a property, which
  results in an extra query.
  I want the color Tags to be fetched in the same query when I fetch the
  Product itself (optionally with lazy loading)
  I guess I need another relation() definition with a Collection join
  and Collection name filter applied.
  I couldn't come up with the code to get me there. How should I tackle
  this?
  Cheers,
  Kees

Sorry for the double post.

Here is how I would construct the colors relation (put this inside
the Product declaration):

def _secondaryjoin():
tag = Tag.__table__
collection = Collection.__table__

exists_clause = exists(
[1],
((tag_collection_table.c.tag_id == tag.c.id)
  (collection.c.name == Colors)),
from_obj=tag_collection_table.join(collection)).correlate(tag)
#  print exists_clause
# EXISTS (SELECT 1
# FROM tag_collection JOIN collection ON collection.id =
tag_collection.collection_id
# WHERE tag_collection.tag_id = tag.id AND collection.name
= :name_1)

retval = ((tag.c.id == product_tag_table.c.tag_id) 
exists_clause)
#  print retval
# tag.id = product_tag.tag_id AND (EXISTS (SELECT 1
# FROM tag_collection JOIN collection ON collection.id =
tag_collection.collection_id
# WHERE tag_collection.tag_id = tag.id AND collection.name
= :name_1))
return retval
colors = relation('Tag',
  secondary=product_tag_table,
  secondaryjoin=_secondaryjoin,
  viewonly=True)
del _secondaryjoin

The key here is adding a custom secondaryjoin to the relation to add
your own filters. The viewonly bit keeps you from trying to modify the
relation, because you should modify the tags relation instead. This
may not be the fastest clause to use as your secondaryjoin, but it was
the most straightforward one I could come up with.

As for eagerloading the colors relation, you can do:
q = session.query(Product)
q = q.options(eagerload(colors))
#  print q
# SELECT product.id AS product_id, product.name AS product_name,
tag_1.id AS tag_1_id, tag_1.name AS tag_1_name
# FROM product LEFT OUTER JOIN product_tag AS product_tag_1 ON
product.id = product_tag_1.product_id LEFT OUTER JOIN tag AS tag_1 ON
tag_1.id = product_tag_1.tag_id AND (EXISTS (SELECT 1
# FROM tag_collection JOIN collection ON collection.id =
tag_collection.collection_id
# WHERE tag_collection.tag_id = tag_1.id AND collection.name
= :name_1))

-Conor

  The model:

  product_tag_table = Table('product_tag', metadata,
      Column('product_id', Integer, ForeignKey('product.id',
          onupdate=CASCADE, ondelete=CASCADE)),
      Column('tag_id', Integer, ForeignKey('tag.id',
          onupdate=CASCADE, ondelete=CASCADE))
  )

  tag_collection_table = Table('tag_collection', metadata,
      Column('tag_id', Integer, ForeignKey('tag.id',
          onupdate=CASCADE, ondelete=CASCADE)),
      Column('collection_id', Integer, ForeignKey('collection.id',
          onupdate=CASCADE, ondelete=CASCADE))
  )

  class Product(DeclarativeBase):
      __tablename__ = 'product'
      id = Column(Integer, autoincrement=True, primary_key=True)
      name = Column(Unicode(255), nullable=False)
      tags = relation('Tag', secondary=product_tag_table,
  backref='products')

      # XXX: REPLACE THIS PROPERTY WITH A FILTERED RELATION?
      def _get_colors(self):
          color_tags=DBSession.query(Collection).\
                  filter(Collection.name==Colors).first().tags
          return filter(lambda tag: tag in self.tags, color_tags)
      colors = property(_get_colors)

  class Tag(DeclarativeBase):
      __tablename__ = 'tag'
      id = Column(Integer, autoincrement=True, primary_key=True)
      name = Column(Unicode(255), unique=True, nullable=False)

  class Collection(DeclarativeBase):
      __tablename__ = 'collection'
      id = Column(Integer, autoincrement=True, primary_key=True)
      name = Column(Unicode(255), unique=True, nullable=False)
      tags = relation('Tag', secondary=tag_collection_table,
  backref='collections')

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the 

[sqlalchemy] SqlAlchemy results differ from its generated SQL

2009-09-22 Thread Mike Driscoll

Hi,

When I run a simple query like this:

qry = session.query(CheckHistory)
qry = qry.filter(and_(CheckHistory.CHECK_DATE = '1/1/2007',
CheckHistory.CHECK_DATE =
'1/1/2008'))
res = qry.all()

I get one CheckHistory row and a None. If I run the echoed SQL code in
my database's query analyzer, I get almost 5000 results. Last Friday,
this worked just fine. However, over the weekend, we upgraded from MS
SQL Server 2000 to 2005. I don't see how this could have messed up
SqlAlchemy, but something weird is going on here.

Does anyone have any hints for troubleshooting this?

I am using SqlAlchemy 0.5.6 on Windows XP with Python 2.5.

Thanks,

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 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Pre-commit validation spanning multiple tables/ORM classes

2009-09-22 Thread Randall Nortman

In my application, I have a set of tables that model parts of what are
conceptually composite objects, and I need to validate that the state
of the objects is coherent before committing them to the database.  In
the course of building up the network of objects, the state may be
temporarily inconsistent (because it will, in general, be impossible
to maintain consistency at every step of the process), but I want to
make sure it is consistent by the time it hits the database.  I think
the answer is to make a SessionExtension and use before_commit(), but
I still have some questions about exactly how that works.

To make the question concrete, I have a one-to-many relationship, and
the relevant state is the state of the parent+children composite.  Any
change to a child's attributes needs to trigger re-validation of the
parent, and obviously any change in membership in the collection of
children needs to trigger revalidation.  In particular, if a child
moves from one parent to another, then *both* parents must be re-
validated before the transaction is committed.  All this validation
needs to occur even though the parent table is not modified in any of
those cases.  And I think I will likely want this to work also in a
many-to-many relationship, where any change to the association table
should trigger validation of all related (or newly unrelated) objects.

Furthermore, I want to work with these objects as individual Parent
and Child objects, not a single ParentWithChildren object.  Or at a
minimum, I want to be able to pass around and modify Child objects on
their own; if I get the Children every time I ask for the Parent,
that's fine.

The @validates decorator is largely useless for this purpose, as it
validates a particular attribute of a particular class, and it gets
called at the wrong time, and in the case of collections, only gets
called on append events, not remove events (afaict).

So if I do this with a SessionExtension.before_commit(), I would have
to iterate through the new, dirty, and deleted instances lists,
inspect the type of each instance, and do whatever is required.  I am
not sure, though, how to handle the case of a change in membership in
the parent/child relationship -- the child instance that is present in
the dirty list will have only the new parent on it -- how do I find
out what the old parent was, so I can validate it?  If a flush has
already occurred, the old value is already lost in the context of the
current transaction, and I think that if I open a new transaction
inside a before_commit() validator I'm just asking for trouble.  Do I
need to instrument the Child class with a descriptor that tracks
changes to the parent and remembers the old parent?  Or can I set the
cascade option in such a way that the old parent will end up in the
dirty list, even though there are no changes to its underlying table,
and in fact it may never have been explicitly loaded into the
session?  (I must admit to be somewhat unsure of what the different
cascade options do -- but they don't seem to be useful for tracking
something like this.)

And lastly, what do I do inside before_commit() if I want to prevent
the commit from proceeding?  Do I just raise an exception?  Any
particular type of exception, or is it my choice?

Sorry for the long question, and thanks for any assistance,

Randall

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Adjacency tree linked list

2009-09-22 Thread Shuaib Osman

Hi guys,

I’m to build an adjacency list in SA and have looked at the
basic_tree.py example provided, however, I need to order the children.
Now I don’t really want to use nested sets and I know linked lists can
be implemented in SA quite easily.

So naturally I tried something like

trees = Table('treenodes', metadata,
Column('id', Integer, Sequence('treenode_id_seq', optional=True),
   primary_key=True),
Column('parent_id', Integer, ForeignKey('treenodes.id'),
nullable=True),
Column('name', String(50), nullable=False),
Column('next_id', Integer, ForeignKey('treenodes.id'),
unique=True, nullable=True)
)

mapper(TreeNode, trees, properties={
'children': relation(TreeNode, cascade=all,
 backref=backref(parent, remote_side=
[trees.c.id]),
 
collection_class=attribute_mapped_collection('name'),
 lazy=False, join_depth=3),
'next' :relation(TreeNode, uselist=False,
 
remote_side=trees.c.id,
 backref=backref('previous',
uselist=False))}
   )

Of course this does not work as it's a many to many relation (and so
needs another table). I would really prefer if I could get away with
just using one table though. Is there a way to do it?

Thanks.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Inheritance + Pseudo-adjacency-list?

2009-09-22 Thread Kevin H

I'm having some trouble developing my model, and was hoping someone on
this list could help...

Here's what I want:
A BizEntity object
A Person and Company object (both descended from BizEntity, using
joined table inheritance)
A Company.employees attribute, which points to a list of Persons who
work for the company
A Person.company attribute, which points back to the company that
person works for

Whenever I try to combine inheritance with this sort of pseudo-
adjacency-list, I get really odd things happening when I try to query
from the tables...like getting the wrong company back when I query by
id.

Any ideas out there?  Anyone done something like this?

MODEL (so far):
(NOTE: the commented out lines are left over from some of my previous
attempts to get things working.)

class BizEntity(Base):
__tablename__ = 'biz_entities'
id = Column('bizentity_id', Integer, primary_key=True)
type =  Column('bizentity_type', String(30), nullable=False)
__mapper_args__ = {'polymorphic_on': type}

class Company(BizEntity):
__tablename__ = 'companies'
id = Column(Integer, ForeignKey('biz_entities.bizentity_id'),
primary_key=True)
name = Column('company_name', String(50))
#~ employees = relation(Person, backref=backref(company,
remote_side=[])
#~ backref('parent', remote_side=[nodes.c.id])

__mapper_args__ = {'polymorphic_identity': 'company'}

class Person(BizEntity):
__tablename__ = 'people'
id = Column('bizentity_id', Integer, ForeignKey
('biz_entities.bizentity_id'), primary_key=True)
first_name = Column('first_name', String(50))
middle_init = Column('middle_init', String(1))
last_name = Column('last_name', String(50))

#~ company = relation(Company, backref=backref('employees',
order_by=id))

__mapper_args__ = {'polymorphic_identity':'person'}


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Pre-commit validation spanning multiple tables/ORM classes

2009-09-22 Thread King Simon-NFHD78

 -Original Message-
 From: sqlalchemy@googlegroups.com 
 [mailto:sqlalch...@googlegroups.com] On Behalf Of Randall Nortman
 Sent: 22 September 2009 16:31
 To: sqlalchemy
 Subject: [sqlalchemy] Pre-commit validation spanning multiple 
 tables/ORM classes
 

[SNIP]

 
 So if I do this with a SessionExtension.before_commit(), I would have
 to iterate through the new, dirty, and deleted instances lists,
 inspect the type of each instance, and do whatever is required.  I am
 not sure, though, how to handle the case of a change in membership in
 the parent/child relationship -- the child instance that is present in
 the dirty list will have only the new parent on it -- how do I find
 out what the old parent was, so I can validate it?  If a flush has
 already occurred, the old value is already lost in the context of the
 current transaction, and I think that if I open a new transaction
 inside a before_commit() validator I'm just asking for trouble.  Do I
 need to instrument the Child class with a descriptor that tracks
 changes to the parent and remembers the old parent?  Or can I set the
 cascade option in such a way that the old parent will end up in the
 dirty list, even though there are no changes to its underlying table,
 and in fact it may never have been explicitly loaded into the
 session?  (I must admit to be somewhat unsure of what the different
 cascade options do -- but they don't seem to be useful for tracking
 something like this.)
 

I can't answer most of your question, but as far as finding out what the
old parent was, could you use the get_history function?

http://www.sqlalchemy.org/docs/05/reference/orm/mapping.html#sqlalchemy
.orm.attributes.get_history

Hope that helps,

Simon

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: checking a relationship exists

2009-09-22 Thread joeformd

thanks - but how does that query specify a town?

It seems like that would just return true if the current user had any
town relationships? Or am I reading it wrong?


On Sep 19, 5:46 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 On Sep 19, 2009, at 11:41 AM, joeformd wrote:



  When we tried that it made a sql query to get all the towns (towns are
  loaded lazily) - that could be an awful lot of information, so this
  would be a much faster query

 so, the most succinct (and efficient) query of all is

 session.scalar(exists().where(user_towns.c.user_id==current_user.id))

 should return True/False right back





  On Sep 19, 4:33 pm, Michael Bayer mike...@zzzcomputing.com wrote:
  On Sep 19, 2009, at 10:19 AM, joeformd wrote:

  Thanks for the speedy response Michael,

  we came up with this:

   current_user_has_town = bool(session.query(User).filter
  (User.id==current_user.id).filter(User.towns.contains
  (current_user)).count())

  which maybe has slightly clearer intent?

  if you already have the current_user, why not just say town in
  current_user.towns
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Pre-commit validation spanning multiple tables/ORM classes

2009-09-22 Thread bojanb

My issue with SQLA validators is that they don't allow inconsistent
state even on fields of a single object, which makes multi-field
validation impossible.

Eg. imagine you have fields tax_id and country_code on a customer
object. For country code 'us', tax_id should be 9 digits long; for
country code 'ca', tax_id should be 15 digits long . If you create
appropriate validators on both fields, you will never be able to
change either the tax_id or country_code of any customer object.

The solution would be to allow inconsistent objects but do validation
just before commit. I've been planning on implementing such validation
for a project I'm working on, so any suggestions are welcome.

On Sep 22, 5:30 pm, Randall Nortman wondercl...@gmail.com wrote:
 In my application, I have a set of tables that model parts of what are
 conceptually composite objects, and I need to validate that the state
 of the objects is coherent before committing them to the database.  In
 the course of building up the network of objects, the state may be
 temporarily inconsistent (because it will, in general, be impossible
 to maintain consistency at every step of the process), but I want to
 make sure it is consistent by the time it hits the database.  I think
 the answer is to make a SessionExtension and use before_commit(), but
 I still have some questions about exactly how that works.

 To make the question concrete, I have a one-to-many relationship, and
 the relevant state is the state of the parent+children composite.  Any
 change to a child's attributes needs to trigger re-validation of the
 parent, and obviously any change in membership in the collection of
 children needs to trigger revalidation.  In particular, if a child
 moves from one parent to another, then *both* parents must be re-
 validated before the transaction is committed.  All this validation
 needs to occur even though the parent table is not modified in any of
 those cases.  And I think I will likely want this to work also in a
 many-to-many relationship, where any change to the association table
 should trigger validation of all related (or newly unrelated) objects.

 Furthermore, I want to work with these objects as individual Parent
 and Child objects, not a single ParentWithChildren object.  Or at a
 minimum, I want to be able to pass around and modify Child objects on
 their own; if I get the Children every time I ask for the Parent,
 that's fine.

 The @validates decorator is largely useless for this purpose, as it
 validates a particular attribute of a particular class, and it gets
 called at the wrong time, and in the case of collections, only gets
 called on append events, not remove events (afaict).

 So if I do this with a SessionExtension.before_commit(), I would have
 to iterate through the new, dirty, and deleted instances lists,
 inspect the type of each instance, and do whatever is required.  I am
 not sure, though, how to handle the case of a change in membership in
 the parent/child relationship -- the child instance that is present in
 the dirty list will have only the new parent on it -- how do I find
 out what the old parent was, so I can validate it?  If a flush has
 already occurred, the old value is already lost in the context of the
 current transaction, and I think that if I open a new transaction
 inside a before_commit() validator I'm just asking for trouble.  Do I
 need to instrument the Child class with a descriptor that tracks
 changes to the parent and remembers the old parent?  Or can I set the
 cascade option in such a way that the old parent will end up in the
 dirty list, even though there are no changes to its underlying table,
 and in fact it may never have been explicitly loaded into the
 session?  (I must admit to be somewhat unsure of what the different
 cascade options do -- but they don't seem to be useful for tracking
 something like this.)

 And lastly, what do I do inside before_commit() if I want to prevent
 the commit from proceeding?  Do I just raise an exception?  Any
 particular type of exception, or is it my choice?

 Sorry for the long question, and thanks for any assistance,

 Randall
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Pre-commit validation spanning multiple tables/ORM classes

2009-09-22 Thread Michael Bayer

bojanb wrote:

 My issue with SQLA validators is that they don't allow inconsistent
 state even on fields of a single object, which makes multi-field
 validation impossible.

meaning, you set A.a and you can't depend on A.b being correct yet ?  
Well sure.  How would you have it done ?  Something has to trigger the
validate event at some point. So if you need to wait for all of A.a,
A.b, A.c, etc. to be setup first, then sure you'd throw your validation
into before_flush() or mapper extension before_insert()/before_update() -
or just tailor your classes' interface as needed, such as A.set_values(a,
b, c).   Personally I opt for the latter since its simple and produces an
immediate validation effect rather than waiting for a flush.




--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Pre-commit validation spanning multiple tables/ORM classes

2009-09-22 Thread bojanb

 meaning, you set A.a and you can't depend on A.b being correct yet ?  
 Well sure.  How would you have it done ?  Something has to trigger the
 validate event at some point.     So if you need to wait for all of A.a,
 A.b, A.c, etc. to be setup first, then sure you'd throw your validation
 into before_flush() or mapper extension before_insert()/before_update() -
 or just tailor your classes' interface as needed, such as A.set_values(a,
 b, c).   Personally I opt for the latter since its simple and produces an
 immediate validation effect rather than waiting for a flush.

What I meant to say is that validators don't fit well with something
that I'm attempting to do. I'll probably implement a little validation
framework that will do validations just before a flush. I'll be sure
to post it here if its interesting enough!
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: SqlAlchemy results differ from its generated SQL

2009-09-22 Thread Michael Bayer


On Sep 22, 2009, at 11:09 AM, Mike Driscoll wrote:


 Hi,

 When I run a simple query like this:

 qry = session.query(CheckHistory)
 qry = qry.filter(and_(CheckHistory.CHECK_DATE = '1/1/2007',
CheckHistory.CHECK_DATE =
 '1/1/2008'))
 res = qry.all()

 I get one CheckHistory row and a None. If I run the echoed SQL code in
 my database's query analyzer, I get almost 5000 results. Last Friday,
 this worked just fine. However, over the weekend, we upgraded from MS
 SQL Server 2000 to 2005. I don't see how this could have messed up
 SqlAlchemy, but something weird is going on here.

 Does anyone have any hints for troubleshooting this?

 I am using SqlAlchemy 0.5.6 on Windows XP with Python 2.5.

turn on echo='debug' on your engine and watch the SQL statements and  
results.   Also query(SomeClass).criterion.all() is not capable of  
returning None within the result list - it only returns entities or  
an empty list.


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: object serializer

2009-09-22 Thread Michael Bayer


On Sep 22, 2009, at 8:34 AM, Julien Cigar wrote:


 Hello,

 I'm busy to make a kind of mapper exporter/serializer. My goal is to
 be able to serialize (in JSON, XML, ...) any Mapper object (including
 relations, etc)

 At the moment I've the following code (not finished at all) :
 http://www.pastie.org/625787

 As you can see I'm iterating over mapper.iterate_properties list (line
 60), and before I goes any further I wondered if it's the right way to
 do it ? (I would like to have all the properties, including column  
 type,
 etc)

its likely the best way at the moment.


 Another question: I see that the property columns of an
 sqlalchemy.orm.properties.ColumnProperty instance is a list and I
 wondered in which cases the list can contains more than one item ?

a single attribute can be mapped to multiple columns explicitly so  
that both columns will always have the same value (see the docs on  
mapping to joins), and its also the case when using composite  
properties.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Inheritance + Pseudo-adjacency-list?

2009-09-22 Thread Michael Bayer


On Sep 22, 2009, at 11:59 AM, Kevin H wrote:


 I'm having some trouble developing my model, and was hoping someone on
 this list could help...

 Here's what I want:
 A BizEntity object
 A Person and Company object (both descended from BizEntity, using
 joined table inheritance)
 A Company.employees attribute, which points to a list of Persons who
 work for the company
 A Person.company attribute, which points back to the company that
 person works for

 Whenever I try to combine inheritance with this sort of pseudo-
 adjacency-list, I get really odd things happening when I try to query
 from the tables...like getting the wrong company back when I query by
 id.

 Any ideas out there?  Anyone done something like this?

I'm doing this.   The first thing to do is to definitely be on 0.5.6  
at the least.

the next thing is to define the employees/company thing only once, as  
a relation/backref pair on just one of your mapped classes.   doing it  
twice will mess things up for sure.

your example also mentions a table called nodes which from  
everything else mentioned below would be erroneous.   you don't need  
remote_side when mapping between Company and Person.

None of this would cause the wrong Company to come back from a  
simple query by id, though.   If that is really the effect you're  
seeing then something more fundamental might be amiss.




 MODEL (so far):
 (NOTE: the commented out lines are left over from some of my previous
 attempts to get things working.)

 class BizEntity(Base):
__tablename__ = 'biz_entities'
id = Column('bizentity_id', Integer, primary_key=True)
type =  Column('bizentity_type', String(30), nullable=False)
__mapper_args__ = {'polymorphic_on': type}

 class Company(BizEntity):
__tablename__ = 'companies'
id = Column(Integer, ForeignKey('biz_entities.bizentity_id'),
 primary_key=True)
name = Column('company_name', String(50))
#~ employees = relation(Person, backref=backref(company,
 remote_side=[])
#~ backref('parent', remote_side=[nodes.c.id])

__mapper_args__ = {'polymorphic_identity': 'company'}

 class Person(BizEntity):
__tablename__ = 'people'
id = Column('bizentity_id', Integer, ForeignKey
 ('biz_entities.bizentity_id'), primary_key=True)
first_name = Column('first_name', String(50))
middle_init = Column('middle_init', String(1))
last_name = Column('last_name', String(50))

#~ company = relation(Company, backref=backref('employees',
 order_by=id))

__mapper_args__ = {'polymorphic_identity':'person'}


 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Beginner inheritance question

2009-09-22 Thread Michael Bayer


On Sep 22, 2009, at 3:42 AM, Iwan wrote:


 Hi there,

 this is perhaps a stupid question, but we can't get it figured out
 from the docs on inheritance...

 Is it possible in sqlalchemy to have a hierarchy of classes of which
 only the root class in the hierarchy is mapped to the database at
 all.  (So the subclasses do not have any persisted attributes of their
 own, and are all in essence mapped to the same table.)

 I suppose single inheritance would work here, but I'd like to keep
 open the option of one day adding one special subclass which DOES in
 fact want to persist extra attributes - this time using joined table
 inheritance.

 Is something (or a mix) like this possible?

it is absolutely possible.   Any subclass mapper that does not have a  
table attribute will map as single table inheritance to the  
superclass.  Any mapper in the inheritance hierarchy that does declare  
table will be mapped to a join of that table against the parent's  
mapped table (or join).   so single/joined can be mixed in any  
combination.

It is possible that there would be some query idiosyncrasies when  
switching a class from single to joined or vice versa - such as if you  
filter on a subclass attribute, joined table  inheritance would  
require such features as with_polymorphic or of_type (or querying  
among the underlying tables directly, something I do often), whereas  
single table inheritance would be more straightforward.  So while  
switching is not that hard, its also not 100% transparent either.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---