Re: [sqlalchemy] Having problem with constructing "update ...from..." with sqlalchemy

2011-09-12 Thread george hu
Thanks Michael,  that solves my problem.

On Mon, Sep 12, 2011 at 3:18 PM, Michael Bayer wrote:

>
> On Sep 12, 2011, at 5:50 PM, Geo wrote:
>
> > I have a tested update ... from.. statement, like so:
>
> UPDATE...FROM syntax, which is non-standard, isn't built into SQLAlchemy
> right now. You'd need to either convert this to use a correlated SELECT
> in the WHERE clause, stick to the SQL string, or use a custom @compiles
> construct - for that we have an example, associated with the trac ticket
> involving an add of this feature, at
> http://www.sqlalchemy.org/trac/attachment/ticket/1944/enhance2.py .The
> construct there might work as it is right now but I haven't tested it.
>
>
>
>
>
> >
> > update distributors set lead_bonus = lead_bonus + a.sum_amt
> > from (
> >select target_member as id, sum(amount) as sum_amt
> >from bonus_gen_history
> >where bonus_type=2 and sub_type=1 and source_member in
> >   (select id
> >from distributors
> >where (extract(epoch from (now()-reg_time))/60>363))
> >group by target_member
> >  ) a
> > where a.id=distributors.id
> >
> > I'm having problem of constructing this statement from sqlalchemy:
> >
> > pass_pending_period = session.query(Distributor.id).filter((func.now()-
> > Distributor.reg_time)/3600>72).subquery()
> >
> > sum_amt = session.query(Bonus_gen_history.target_member,
> > func.sum(Bonus_gen_history.amount).label('sm')).\
> >
> > filter(Bonus_gen_history.bonus_type==BonusType.sponsorBonus).\
> >filter(Bonus_gen_history.tran_type==TranType.addPd).\
> >
> > filter(Bonus_gen_history.source_member.in_(pass_pending_period)).
> >group_by(Bonus_gen_history.target_member).subquery()
> >
> >
> > q = session.query(Distributor).update({Distributor.sponsor_bonus:
> > Distributor.sponsor_bonus+(sum_amt.c.sm)})
> >
> > I keep getting the following error message:
> >
> > sqlalchemy.exc.ProgrammingError: (ProgrammingError) missing FROM-
> > clause entry for table "anon_1"
> > LINE 1: ...s SET sponsor_bonus=(distributors.sponsor_bonus +
> > anon_1.sm)
> > ^
> > 'UPDATE distributors SET sponsor_bonus=(distributors.sponsor_bonus +
> > anon_1.sm)' {}
> >
> > And I can't figure out how to add the "FROM-clause" in the above
> > query.
> >
> > Can somebody help me out?
> >
> >
> > --
> > 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.
>
>

-- 
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] use session inside the class

2011-09-02 Thread george hu
Thanks Michael, that gives me more understanding of using the session.
Actually the DBSession is initialized from:

DBSession = scoped_session(sessionmaker(
 extension=ZopeTransactionExtension()))


as the following description:

ZopeTransactionExtension is a little piece that makes sure every session
that opens joins an active transaction. So if you were to open 5 session's,
they will all join the same transaction. That way if you commit or rollback
the transaction, all the work done by the either of the 5 sessions will
follow suit. The transaction module ("transaction.commit()") is key here.

pyramid_tm tries to make setting up a transaction straightforward ... it
starts one upon request entry, all scoped database sessions join it... and
then at the end of the request, if it discovered an error, it will rollback
the transaction. Otherwise, the transaction will be committed. That way
view-level code never has to create or close/commit/rollback the transaction
manually.

Mostly session.flush() is for making sure your database model instances get
their primary keys filled in without committing the transaction.

So inside a view all you gotta do is:

def myview(request):
session = DBsession()
session.add(model)

pyramid_tm will make sure session is committed or rolled back appropriately.

The session's discussion always makes me confusion, what about in my "model"
I define something like this:

def foobar(self, session.):

session.add(self)





On Fri, Sep 2, 2011 at 6:58 AM, Michael Bayer wrote:

>
> On Sep 2, 2011, at 3:02 AM, Wichert Akkerman wrote:
>
> > On 09/02/2011 03:31 AM, Michael Bayer wrote:
> >> With SQLAlchemy you should have an ongoing transaction/session defined
> externally to individual operations on your mapped objects - SQLA uses the
> "unit of work" pattern which specifically is about grouping related
> persistence/query operations together. The usage you have above is still
> thinking in the "active record" style of things - "session per individual
> persistence operation" - and won't take full advantage of SQLA's way of
> doing things.
> >
> > I can see this  being useful if you need a id generated by a serial
> though. In places where I need something like that I use
> object_session(self), which seems to work well.
>
>
> OK let me clarify -   it is *entirely OK*, even encouraged, to make usage
> of the Session inside of object methods.   object_session(self) to do
> queries, add() more things, as well as using a contextual Session to add()
> new objects from within a @classmethod.   This is commonplace and necessary.
>   Use Sessions freely anywhere and everywhere.
>
> What is *usually not needed*, is to create a brand new Session inside of an
> object method, and then to commit() the transaction it uses.   Usually,
> there should be an external context that all objects are interfacing with,
> i.e., a Session.   If you don't have an ongoing context at all, and are
> adding "x = Session(); x.add(self); x.commit()" inside of all your methods
> as the normal way of doing things, that is definitely the wrong way to do
> it.
>
> The case where you *may* want to build a brand new Session and commit it
> inside of a method is when you specifically want some operation to occur in
> a transaction that is distinct from everything else that's going on ;  I use
> such a notion to write operations to a "logging" table in my app, so that a
> web GUI can read that one table for status while some long operation is
> going on, and also so that the log of activity remains if the long running
> operation fails, and the transaction is rolled back.  But even in that case,
> I have a single function in my app called log() that's at the module level
> which does this (with lots of behavioral options).
>
> The main thing I want to get across is, all apps should ideally have some
> standard, defined-in-only-one-or-two-places system of initiating Sessions
> and establishing where the scope of that Session ends for the majority of
> operations, and you should catch yourself if you're trying to avoid building
> that pattern that for some reason.
>
> --
> 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.