RE: [sqlalchemy] update existing row

2011-08-01 Thread King Simon-NFHD78
vitsin wrote:
 hi,
 can't figure out why raw SQL works fine, but update() is not working:
 1.working raw SQL:
 self.session.execute(update public.my_table set
 status='L',updated_at=now() where my_name='%s' % (self.my_name))
 
 2.non working update() from Alchemy:
 s = aliased(MyTable)
 query = self.session.query(s).filter(s.my_name==self.my_name)
 sts = self.session.execute(query).fetchone()
 sts.update(values={'status':'L'})
 
 sts.update(values={s.status:'L'})
   File /usr/lib/python2.6/dist-packages/sqlalchemy/engine/base.py,
 line 2097, in _key_fallback
 Could not locate column in row for column '%s' % key)
 sqlalchemy.exc.NoSuchColumnError: Could not locate column in row for
 column 'update'
 
 
 But Column s.status exists ...
 appreciate any help,
 --vs

In your example, 'sts' represents a single row from the database. These
objects don't have an 'update' method, which is why you are getting that
error. It thinks you are trying to access a column called 'update'
instead.

You appear to be using the SQL Expression language (ie. MyTable is
created using sqlalchemy.Table). You can create an 'update' statement
using MyTable.update(). Examples are at:

http://www.sqlalchemy.org/docs/core/tutorial.html#inserts-and-updates

(You should be able to substitute conn.execute() with session.execute())

However, you might be interested in using the ORM part of SQLAlchemy:

http://www.sqlalchemy.org/docs/orm/tutorial.html

Your usage would then look something like this (assuming MyMappedClass
is the class mapped to MyTable):

s = MyMappedClass
query = self.session.query(s).filter(s.my_name == self.my_name)
sts = query.first()
sts.status = 'L'
self.session.flush()

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] Updating user interface after rollback (using after_rollback SessionExtension?)

2011-08-01 Thread Torsten Landschoff
Hello world,

I am tearing my hair about my SQLAlchemy usage in a GUI application,
especially to get it error tolerant.

Usually the GUI filters user inputs before they are thrown at SQLAlchemy
to store it into the database. If that fails, however, it can happen
that data is thrown at the database that leads to a rollback because of
e.g. violated foreign key constraints.

If that happens, the session rolls back (fine) but the GUI still shows
the state that I tried to write into the database. Being MVC, I would
need all database object to fire a changed event so they are pulled
fresh from the database.

I tried using the after_commit extension (SQLAlchemy 0.6.8) to do this.
Paraphrased, this works like this:

def after_rollback(self, session):
for instance in session:
instance.signal_changed()

This works fine if the transaction being rolled back is the toplevel
transaction. However, if that is a nested transaction, this destroys my
session state (as the listeners try to load from the database):

InvalidRequestError: This Session's transaction has been rolled back by
a nested rollback() call.  To begin a new transaction, issue
Session.rollback() first.

So I would need the callback only after the rollback of the toplevel
session occurred. I tried looking at the _is_transaction_boundary
property of session.transaction:

def after_rollback(self, session):
if session.transaction._is_transaction_boundary:
for instance in session:
instance.signal_changed()

This stops the exceptions, but it also never comes to signal_changed if
subtransactions are rolled back. It looks like I only get a single event
for the innermost transaction?!


What would be a sane way to implement this? I also looked at the
MapperExtension in the hope that there is a callback whenever an
instance is expired, but does not seem to be such a thing.

Hints welcome,

Torsten

-- 
DYNAmore Gesellschaft fuer Ingenieurdienstleistungen mbH
Torsten Landschoff

Office Dresden
Tel: +49-(0)351-4519587
Fax: +49-(0)351-4519561

mailto:torsten.landsch...@dynamore.de
http://www.dynamore.de

Registration court: Mannheim, HRB: 109659, based in Karlsruhe,
Managing director:  Prof. Dr. K. Schweizerhof, Dipl.-Math. U. Franz

-- 
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] Relationship spanning on multiple tables

2011-08-01 Thread neurino
I'm trying to get some relationships spanning on multiple tables (4 or
5).

While I got the `4 tables` one working on first attempt (I was
surpized I could...) I can't get the `5 tables` one to work while the
code is almost the same.

Moreover with the first relationship if I add adding `viewonly=True`
initialization fails.

I just need these to get (not even set) some values with convenience
of SA attributes.

I published a working example on pastebin:

http://pastebin.com/RsZ6GCRq

I hope someone can sort out this thing, thank you.

Greetings
neurino

-- 
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] Building hierarchy tree in reverse

2011-08-01 Thread Vlad K.


Hi.

I have a problem and am not sure where to begin. I need to construct a 
hierarchy tree, something like adjacency_list but in reverse. More 
precisely, I need entire branch but only the branch containing given 
node ID. In practice, I need this for a product category tree menu which 
shows items in the currently selected branch only (where for example I 
don't need children of bba, or ba, or A because node ID is not in their 
branches):


A
B
ba
bb
bba
bbb
bbc - this node id is given at first
bbca
bbcb
bbcd
bc
bd
C
D


Basically, the way I see it, I need to:

1. Find node by ID
2. Find node's children
3. Find node's siblings
4. Node's parent becomes node, repeat from step 3 as long as there's a 
parent


The table is constructed with parent_id foreign key reference to itself, 
and I can fetch entire tree at level X using joinedload_all as given in 
this example:


http://www.sqlalchemy.org/trac/browser/examples/adjacency_list/adjacency_list.py

I have an idea how to do it manually but I was wondering if there is a 
feature of SQLAlchemy I could use. I'd google for any similar problems 
or implementations since I don't think this is an uncommon problem, but 
I'm not sure what to look for.


Thanks!

--

.oO V Oo.

--
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] Are data really in database using session.comit

2011-08-01 Thread Eduardo
Daer all

I have a following problem :

Session = sessionmaker(bind=engine)

session = Session()
for item in items:
item1 = session.query(item)
if len(item1)==0:
session.add(item1)
session.commit()

The session is valid for a loop and I write items in a database during
each iteration. Can it happen that if an item is identical to the
previous one, the session.commit() will not make it to write the
previous item in the database before the query of the next iteration
is executed and the next session.commit() will fail because of
sqlalchemy.exc.IntegrityError: (IntegrityError) duplicate key value
violates unique constraint.
How can I make sure that the previous item is already in the database
before the query in the next iteration is carried out?
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.



Re: [sqlalchemy] Updating user interface after rollback (using after_rollback SessionExtension?)

2011-08-01 Thread Michael Bayer

On Aug 1, 2011, at 6:25 AM, Torsten Landschoff wrote:

 Hello world,
 
 I am tearing my hair about my SQLAlchemy usage in a GUI application,
 especially to get it error tolerant.
 
 Usually the GUI filters user inputs before they are thrown at SQLAlchemy
 to store it into the database. If that fails, however, it can happen
 that data is thrown at the database that leads to a rollback because of
 e.g. violated foreign key constraints.
 
 If that happens, the session rolls back (fine) but the GUI still shows
 the state that I tried to write into the database. Being MVC, I would
 need all database object to fire a changed event so they are pulled
 fresh from the database.

The Session's default behavior is to expire fully the state present after a 
rollback occurs.   The next access of any attribute will guaranteed pull fresh 
from the DB in a new transaction. 

I'm assuming you know this, and that there is something additional here you're 
looking for, like an event to the GUI to actually re-access the attributes, or 
something.

 
 I tried using the after_commit extension (SQLAlchemy 0.6.8) to do this.
 Paraphrased, this works like this:
 
def after_rollback(self, session):
for instance in session:
instance.signal_changed()
 
 This works fine if the transaction being rolled back is the toplevel
 transaction. However, if that is a nested transaction, this destroys my
 session state (as the listeners try to load from the database):
 
 InvalidRequestError: This Session's transaction has been rolled back by
 a nested rollback() call.  To begin a new transaction, issue
 Session.rollback() first.

A surprise for me.Yes the after_rollback() seems to only fire after an 
actual database rollback.  This is a bug in that there is no way to catch soft 
rollbacks.  I can't change the event, as it is integral in transactional 
extensions like that supplied for Zope; a new one will have to be added and the 
docs for after_rollback() will need to be updated.

Ticket #2241 is added for this and is completed.   You can now use the 0.7 tip 
and use the after_soft_rollback() event in conjunction with the is_active flag:

@event.listens_for(Session, after_soft_rollback)
def do_something(session, previous_transaction):
if session.is_active:
session.execute(select * from some_table)

http://www.sqlalchemy.org/trac/ticket/2241
http://hg.sqlalchemy.org/sqlalchemy/rev/94d54a7e4d49





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



Re: [sqlalchemy] Are data really in database using session.comit

2011-08-01 Thread Michael Bayer

On Aug 1, 2011, at 11:07 AM, Eduardo wrote:

 Daer all
 
 I have a following problem :
 
 Session = sessionmaker(bind=engine)
 
 session = Session()
 for item in items:
item1 = session.query(item)
if len(item1)==0:
session.add(item1)
session.commit()
 
 The session is valid for a loop and I write items in a database during
 each iteration. Can it happen that if an item is identical to the
 previous one, the session.commit() will not make it to write the
 previous item in the database before the query of the next iteration
 is executed and the next session.commit() will fail because of
 sqlalchemy.exc.IntegrityError: (IntegrityError) duplicate key value
 violates unique constraint.
 How can I make sure that the previous item is already in the database
 before the query in the next iteration is carried out?

I'd get the data in order before going in, and most likely do not commit() on 
every insert, this is wasteful.  Assuming the primary key of item is 
item.id:

# uniquify on id
items_by_id = dict((item.id, item) for item in items)

for item in items_by_id.values():
   # merge each.
   item = session.merge(item)

session.commit()

If the above approach is emitting too many SELECTs for your taste, an 
additional optimization would be to pre-load the existing items, such as:

# get the ids into a dict
items_by_id = dict((item.id, item) for item in items)

# load whatever is present first in one SELECT, keep them in memory 
# inside of existing_items
existing_items = session.query(Item).filter(Item.id.in_(items_by_id)).all()

# then do the loop + merge()

-- 
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] Simple one-to-one translation with hybrid_attribute

2011-08-01 Thread Ross Vandegrift
Hello everyone,

Trying to use hybrid_attribute to provide friendly names for integers
representing object states.  Storage and retrieval works fine, but I
can't get filtering working.  I want the translation to happen on the
Python side prior to filling in the query parameters, but
hybrid_attribute is thinking the DB should do it.  Example at the
bottom.

I don't really understand how to write the @state.expression the way I
want things to happen.

Thanks,
Ross




import sqlalchemy as sa
import sqlalchemy.orm as orm
from sqlalchemy.ext.hybrid import hybrid_property, hybrid_method
from sqlalchemy.ext.declarative import declarative_base

engine = sa.create_engine('sqlite:///:memory:', echo=True)
Base = declarative_base()
Session = orm.scoped_session(orm.sessionmaker(autocommit=False,
  autoflush=False,
  bind=engine))
statei2a = {
0 : captured,
1 : registered,
2 : prepared,
}
statea2i = dict((v, k) for k, v in statei2a.iteritems())

class Device(Base):
__tablename__ = device

id = sa.Column(sa.Integer, primary_key=True)
statenum = sa.Column(sa.Integer, nullable=False, default=0)

def __init__(self, state):
self.state = state

@hybrid_property
def state(self):
return statei2a[self.statenum]

@state.setter
def state(self, state):
self.statenum = statea2i[state]

@state.expression
def state(self):
return statea2i[self.statenum]

Base.metadata.create_all(engine)

d1 = Device(captured)
d2 = Device(registered)
d3 = Device(prepared)
Session.add_all([d1, d2, d3])
Session.commit()

q = Session.query(Device)
q.filter_by(state=captured)
q.filter(Device.state  0)



signature.asc
Description: This is a digitally signed message part


Re: [sqlalchemy] Relationship spanning on multiple tables

2011-08-01 Thread Michael Bayer
'transm_limit': relationship(SurfaceRes, single_parent=True,
#uselist=False,
#primaryjoin=and_(
#user_stratigraphies.c.id_prov==provinces.c.id,
#provinces.c.id_cz==transm_limits.c.id_cz,
#user_stratigraphies.c.id_str==stratigraphies.c.id,
#stratigraphies.c.id_tec==tech_elements_classes.c.id,
#tech_elements_classes.c.id_tu==transm_limits.c.id_tu,
#),

this fails because you aren't joining to the table to which SurfaceRes is 
mapped, surface_res.



On Aug 1, 2011, at 7:02 AM, neurino wrote:

 I'm trying to get some relationships spanning on multiple tables (4 or
 5).
 
 While I got the `4 tables` one working on first attempt (I was
 surpized I could...) I can't get the `5 tables` one to work while the
 code is almost the same.
 
 Moreover with the first relationship if I add adding `viewonly=True`
 initialization fails.
 
 I just need these to get (not even set) some values with convenience
 of SA attributes.
 
 I published a working example on pastebin:
 
 http://pastebin.com/RsZ6GCRq
 
 I hope someone can sort out this thing, thank you.
 
 Greetings
 neurino
 
 -- 
 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.
 

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



Re: [sqlalchemy] Simple one-to-one translation with hybrid_attribute

2011-08-01 Thread Michael Bayer

On Aug 1, 2011, at 5:08 PM, Ross Vandegrift wrote:

 Hello everyone,
 
 Trying to use hybrid_attribute to provide friendly names for integers
 representing object states.  Storage and retrieval works fine, but I
 can't get filtering working.  I want the translation to happen on the
 Python side prior to filling in the query parameters, but
 hybrid_attribute is thinking the DB should do it.  Example at the
 bottom.
 
 I don't really understand how to write the @state.expression the way I
 want things to happen.

 statei2a = {
0 : captured,
1 : registered,
2 : prepared,
 }
 statea2i = dict((v, k) for k, v in statei2a.iteritems())
 
 class Device(Base):
__tablename__ = device
 
id = sa.Column(sa.Integer, primary_key=True)
statenum = sa.Column(sa.Integer, nullable=False, default=0)
 
def __init__(self, state):
self.state = state
 
@hybrid_property
def state(self):
return statei2a[self.statenum]
 
@state.setter
def state(self, state):
self.statenum = statea2i[state]
 
@state.expression
def state(self):
return statea2i[self.statenum]

You're looking to convert from int-string using a mapping in a SQL expression, 
so I think you'd need to write @state.expression as a CASE statement.   

from sqlalchemy import case

   @state.expression
   def state(self):
   return case(self.statenum, statei2a)






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



Re: [sqlalchemy] Simple one-to-one translation with hybrid_attribute

2011-08-01 Thread Ross Vandegrift
On Mon, 2011-08-01 at 17:22 -0400, Michael Bayer wrote:
 You're looking to convert from int-string using a mapping in a SQL
 expression, so I think you'd need to write @state.expression as a CASE
 statement.   
 
 from sqlalchemy import case
 
@state.expression
def state(self):
return case(self.statenum, statei2a)

Exactly what I needed, works like a charm - thank you so much!

For the archives - the args are flipped above.  Should be
case(statei2a, self.statenum).

Thanks,
Ross


signature.asc
Description: This is a digitally signed message part


[sqlalchemy] Integrity error when using association_proxy - one of the foreign keys is missing

2011-08-01 Thread somewhatofftheway
Hi,

I'm trying to convert a 'simple' many-to-many relationship to an
association object in order to allow the relationship to have
attributes. I've followed the code in examples/association/
proxied_association.py fairly closely (or so I thought) but it isn't
working for me.

As an example, let's say I am trying to create a relationship between
an RSS feed and the pages from the feed but I want a feed_date on the
relationship. Currently, my code look something like this:

class Page (Base):
__tablename__ = 'pages'
id = Column(Integer, primary_key=True)

posts = relationship(Post, cascade=all, delete-orphan,
backref='pages')
feeds = association_proxy(feeds, feed)


class Post(Base)
__tablename__ = 'pages_feeds'
page_id = Column(Integer, ForeignKey('pages.id'),
primary_key=True)
feed_id = Column(Integer, ForeignKey('feeds.id'),
primary_key=True)
feed = relationship(Feed, lazy='joined')

I haven't changed the Feed class at all.

When I do something along the lines of:

page = Page()
feed = Feed()
page.feeds.append(feed)

the query that is issued is as follows:

IntegrityError: (IntegrityError) pages_feeds.feed_id may not be NULL
u'INSERT INTO pages_feeds (page_id) VALUES (?)' (1,)

So, clearly I have missed out the part of the config that explains
that adds in the second foreign key. Could anybody point me to where
please?

Thanks,
Ben





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



Re: [sqlalchemy] Integrity error when using association_proxy - one of the foreign keys is missing

2011-08-01 Thread Michael Bayer

On Aug 1, 2011, at 8:34 PM, somewhatofftheway wrote:

 Hi,
 
 I'm trying to convert a 'simple' many-to-many relationship to an
 association object in order to allow the relationship to have
 attributes. I've followed the code in examples/association/
 proxied_association.py fairly closely (or so I thought) but it isn't
 working for me.
 
 As an example, let's say I am trying to create a relationship between
 an RSS feed and the pages from the feed but I want a feed_date on the
 relationship. Currently, my code look something like this:
 
 class Page (Base):
__tablename__ = 'pages'
id = Column(Integer, primary_key=True)
 
posts = relationship(Post, cascade=all, delete-orphan,
backref='pages')
feeds = association_proxy(feeds, feed)
 
 
 class Post(Base)
__tablename__ = 'pages_feeds'
page_id = Column(Integer, ForeignKey('pages.id'),
 primary_key=True)
feed_id = Column(Integer, ForeignKey('feeds.id'),
 primary_key=True)
feed = relationship(Feed, lazy='joined')
 
 I haven't changed the Feed class at all.
 
 When I do something along the lines of:
 
 page = Page()
 feed = Feed()
 page.feeds.append(feed)
 
 the query that is issued is as follows:
 
 IntegrityError: (IntegrityError) pages_feeds.feed_id may not be NULL
 u'INSERT INTO pages_feeds (page_id) VALUES (?)' (1,)
 
 So, clearly I have missed out the part of the config that explains
 that adds in the second foreign key. Could anybody point me to where
 please?

you need a constructor and/or creator that generates Post() with the feed 
attached to it, like def __init__(self, feed): self.feed = feed, then the assoc 
proxy with creator=Post.

-- 
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: Building hierarchy tree in reverse

2011-08-01 Thread Gunnlaugur Briem
You could look for recursive CTE (Common Table Expressions), if your 
database engine supports such queries. See e.g. 
http://www.postgresql.org/docs/8.4/static/queries-with.html for PostgreSQL. 
That allows arbitrary-depth queries, as opposed to join chains that have to 
assume a fixed depth. You could probably apply two recursive queries, one 
downward and one upward from the given node, to avoid querying the whole 
tree.

SQLAlchemy has no support for CTEs directly, though of course you can 
construct the query manually and execute and fetch results through 
SQLAlchemy. You *can* get some support for recursive queries 
under SQLAlchemy in https://github.com/marplatense/sqla_hierarchy/ but be 
warned, that project is ... youthful :)

Regards,

- Gulli

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/g7-7S4mBC3wJ.
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.