Re: [sqlalchemy] Re: AuditLog/History logging

2010-11-04 Thread chaouche yacine
You can place triggers in your class definitions, there are decorators for 
this, 
see @afterUpdate, @beforeUpdate, @afterDelete, @beforeDelete, @afterInsert, 
@beforeInsert. You can search for these in the documentation, I am not sure of 
the exact spelling tho.

Cheers,

Y.chaouche




- Original Message 
From: Gopalakrishnan Subramani gopalakrishnan.subram...@gmail.com
To: sqlalchemy sqlalchemy@googlegroups.com
Sent: Wed, November 3, 2010 6:21:01 PM
Subject: [sqlalchemy] Re: AuditLog/History logging

Chaouche, Thank you for information.

At the instance level, how will I know whether the instance going to
be deleted or updated or insert. How do I get the property?

And during update, how to identify which field has been modified?

Regards,

Krish

On Nov 3, 6:30 pm, chaouche yacine yacinechaou...@yahoo.com wrote:
 http://www.sqlalchemy.org/docs/orm/examples.html?highlight=versioning...

 You can find other interesting recipes in :

 http://www.sqlalchemy.org/trac/wiki/UsageRecipes

 Cheers,

 Y.Chaouche

 - Original Message 
 From: Gopalakrishnan Subramani gopalakrishnan.subram...@gmail.com
 To: sqlalchemy sqlalchemy@googlegroups.com
 Sent: Wed, November 3, 2010 5:21:32 AM
 Subject: [sqlalchemy] AuditLog/History logging

 We have around 10 different tables in the database and we use
 sqlalchemy's declarative base style table definition. We are happy
 about it.

 Now we need to have auditlog/history of changes made to database
 records.

 For example, the entry could be new recorded added or existing record
 updated or deleted. These information should be reflected in the
 database table called history.

 So we end up writing very simular code for every tables in our
 database for each crud operation.

 I am thinking whether we can have simplified solution like

 1. We define our own custom class derived from declarative_base
 instance
 2. We derive the rest of our classes from our own custom class
 mentioned in the step 1
 3. Whenever there is changes in the record, Sqlalchemy to give
 callback on post/pre operation and we capture those changes in the
 derived class and use the history class to write the changes to the
 database.

 So we can derive all our future classes from this model and I will be
 free to handle the rest of the information.

 Can you please help me to implement this?

 Regards,

 Krisj

 --
 You received this message because you are subscribed to the Google Groups
 sqlalchemy group.
 To post to this group, send email to sqlalch...@googlegroups.com.
 To unsubscribe from this group, send email to
 sqlalchemy+unsubscr...@googlegroups.com.
 For more options, visit this group 
athttp://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 sqlalch...@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 sqlalch...@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] AuditLog/History logging

2010-11-03 Thread chaouche yacine
I know that elixir has an extension that does just this. You don't have to 
subclass, you just use a acts_as_versioned statement in your class definition 
and that's it. 


In addition, it will let you get the object at any of its verison (you can 
revert back changes, a sort of undo funcitonnality that spans over time) via 
the get_as_of method 


http://elixir.ematia.de/apidocs/elixir.ext.versioned.html

I wonder if sqlalchemy has an equivalent extension ?

Cheers,

Y.Chaouche




- Original Message 
From: Gopalakrishnan Subramani gopalakrishnan.subram...@gmail.com
To: sqlalchemy sqlalchemy@googlegroups.com
Sent: Wed, November 3, 2010 5:21:32 AM
Subject: [sqlalchemy] AuditLog/History logging

We have around 10 different tables in the database and we use
sqlalchemy's declarative base style table definition. We are happy
about it.

Now we need to have auditlog/history of changes made to database
records.

For example, the entry could be new recorded added or existing record
updated or deleted. These information should be reflected in the
database table called history.

So we end up writing very simular code for every tables in our
database for each crud operation.

I am thinking whether we can have simplified solution like

1. We define our own custom class derived from declarative_base
instance
2. We derive the rest of our classes from our own custom class
mentioned in the step 1
3. Whenever there is changes in the record, Sqlalchemy to give
callback on post/pre operation and we capture those changes in the
derived class and use the history class to write the changes to the
database.

So we can derive all our future classes from this model and I will be
free to handle the rest of the information.

Can you please help me to implement this?

Regards,

Krisj

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@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 sqlalch...@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] AuditLog/History logging

2010-11-03 Thread chaouche yacine
http://www.sqlalchemy.org/docs/orm/examples.html?highlight=versioning#versioning

You can find other interesting recipes in :

http://www.sqlalchemy.org/trac/wiki/UsageRecipes

Cheers,

Y.Chaouche

- Original Message 
From: Gopalakrishnan Subramani gopalakrishnan.subram...@gmail.com
To: sqlalchemy sqlalchemy@googlegroups.com
Sent: Wed, November 3, 2010 5:21:32 AM
Subject: [sqlalchemy] AuditLog/History logging

We have around 10 different tables in the database and we use
sqlalchemy's declarative base style table definition. We are happy
about it.

Now we need to have auditlog/history of changes made to database
records.

For example, the entry could be new recorded added or existing record
updated or deleted. These information should be reflected in the
database table called history.

So we end up writing very simular code for every tables in our
database for each crud operation.

I am thinking whether we can have simplified solution like

1. We define our own custom class derived from declarative_base
instance
2. We derive the rest of our classes from our own custom class
mentioned in the step 1
3. Whenever there is changes in the record, Sqlalchemy to give
callback on post/pre operation and we capture those changes in the
derived class and use the history class to write the changes to the
database.

So we can derive all our future classes from this model and I will be
free to handle the rest of the information.

Can you please help me to implement this?

Regards,

Krisj

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@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 sqlalch...@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] Checking the availablity of a booked Item

2010-10-20 Thread chaouche yacine
Did you try :

qry = qry.outerjoin(Appointment.person).filter(Appointment.id == None) ?

I have the intuition that sqlalchemy can guess on what foreign keys the join 
should operate based on how you declared your relations.

What about (if Person.appointments exists):

qry = qry.outerjoin(Person.appointments).filter(Appointment.id == None) ?

I don't think you'd have the same results (join order matters).


Y.Chaouche



--- On Wed, 10/20/10, Thadeus Burgess thade...@thadeusb.com wrote:

From: Thadeus Burgess thade...@thadeusb.com
Subject: Re: [sqlalchemy] Checking the availablity of a booked Item
To: sqlalchemy@googlegroups.com
Date: Wednesday, October 20, 2010, 8:27 AM

Here is an example of how I use outerjoin to perform a similar query.


class Survey, def get_apps(self):

Get all persons who are over 18 and do not have an appointment but have this 
survey.



qry = Person.query.filter(Person.age  18)

qry = qry.outerjoin((Appointment,
    (Appointment.id_person == Person.id)
    (Appointment.id_survey == self.id))). \


  filter(Appointment.id == None) #: Or != None, depending on the 
type of join.

#: I go and append a few more outer joins here as well,# but they look exactly 
the same just different tables.

The syntax of the outerjoin arguments is a tuple containing (Table to join 
to, whereclause to join on).



Hopefully this helps you. Basically, I just look at the coding horror site for 
the kind of join I want to perform, and modify the syntax above to make it 
match the SQL.

--
Thadeus





On Mon, Oct 18, 2010 at 10:38 AM, chaouche yacine yacinechaou...@yahoo.com 
wrote:


Hello,

I think outerjoin is just a join with an isouter = True, and above all the 
problem was not there anyway. The problem was only about ordering the joins. 
The correct python code was :



Face.query.outerjoin(Face.bookings).filter(cond).all()

instead of

Face.query.outerjoin(Booking.faces).filter(cond).all()

Which looks more intuitive to me, because I'm doing joins between Face and 
Booking (thus putting Booking in the outerjoin, not Face again as in the first 
code). I can't understand the logic of the (correct) first one, but it works ! 
Or is it two errors cancelling each other ?



Y.Chaouche




--- On Thu, 10/14/10, Thadeus Burgess thade...@thadeusb.com wrote:



From: Thadeus
 Burgess thade...@thadeusb.com
Subject: Re: [sqlalchemy] Checking the availablity of a booked Item
To: sqlalchemy@googlegroups.com


Date: Thursday, October 14, 2010, 8:42 AM

http://www.sqlalchemy.org/docs/reference/orm/query.html#sqlalchemy.orm.join



isouter = True

--
Thadeus







On Thu, Oct 14, 2010 at 10:26 AM, chaouche yacine yacinechaou...@yahoo.com 
wrote:




Here's the SQL I got : 

SELECT face.id AS face_id 




FROM face 
LEFT OUTER JOIN face_bookings__booking_faces AS face_bookings__booking_faces_1 
        ON face.id = face_bookings__booking_faces_1.face_id 


LEFT OUTER JOIN booking 


        ON booking.id = face_bookings__booking_faces_1.booking_id 
JOIN time_period ON booking.time_period_id = time_period.id 




WHERE 
  time_period.start_date  %(start_date_1)s 
  OR 
  time_period.end_date  %(end_date_1)s


With the following code : 






class
 Booking(BaseModel):
    




    
    using_options(tablename=booking)





    reprattr    =  time_period




   
 faces   = ManyToMany(Face)
    # A client has one and only one booking per time period




    time_period = ManyToOne(TimePeriod)
    




    @classmethod
    def
 get_available_faces(self,time_period):
    




    Return faces that are not booked during the given time_period.
    




    from timeperiod import TimePeriod
    from face   import Face




    
    start_date_cond = TimePeriod.start_date  time_period.end_date




    end_date_cond   = TimePeriod.end_date    time_period.start_date




    unbooked    = or_(start_date_cond,end_date_cond)





    # query = 
Face.query.filter(Face.bookings.any(Booking.time_period.has(unbooked)))




    # return query.all()





    query =
 Face.query.filter(unbooked)
    #return query.all()




    query = query.outerjoin(Face.bookings)
    #return query.all()




    query = query.join(Booking.time_period)
    return query.all()






And still not the expected results (it should return faces with no bookings at 
all but it doesen't).

Thanks for any help.

Y.Chaouche





--- On Wed, 10/13/10, chaouche yacine yacinechaou...@yahoo.com wrote:





From: chaouche yacine yacinechaou...@yahoo.com
Subject: Re: [sqlalchemy] Checking the availablity of a booked Item


To: sqlalchemy@googlegroups.com


Date: Wednesday, October 13, 2010, 5:25 AM

Thank you Thadeus, I believe
 Face.query.filter(filter_cond).outerjoin(join_clause).all() does a full 
outerjoin, or is there another way to do it ?

Y.Chaouche





--- On Wed, 10/13/10, Thadeus

Re: [sqlalchemy] Checking the availablity of a booked Item

2010-10-18 Thread chaouche yacine
Hello,

I think outerjoin is just a join with an isouter = True, and above all the 
problem was not there anyway. The problem was only about ordering the joins. 
The correct python code was :

Face.query.outerjoin(Face.bookings).filter(cond).all()

instead of

Face.query.outerjoin(Booking.faces).filter(cond).all()

Which looks more intuitive to me, because I'm doing joins between Face and 
Booking (thus putting Booking in the outerjoin, not Face again as in the first 
code). I can't understand the logic of the (correct) first one, but it works ! 
Or is it two errors cancelling each other ?

Y.Chaouche




--- On Thu, 10/14/10, Thadeus Burgess thade...@thadeusb.com wrote:

From: Thadeus Burgess thade...@thadeusb.com
Subject: Re: [sqlalchemy] Checking the availablity of a booked Item
To: sqlalchemy@googlegroups.com
Date: Thursday, October 14, 2010, 8:42 AM

http://www.sqlalchemy.org/docs/reference/orm/query.html#sqlalchemy.orm.join

isouter = True

--
Thadeus







On Thu, Oct 14, 2010 at 10:26 AM, chaouche yacine yacinechaou...@yahoo.com 
wrote:


Here's the SQL I got : 

SELECT face.id AS face_id 


FROM face 
LEFT OUTER JOIN face_bookings__booking_faces AS face_bookings__booking_faces_1 
        ON face.id = face_bookings__booking_faces_1.face_id 
LEFT OUTER JOIN booking 


        ON booking.id = face_bookings__booking_faces_1.booking_id 
JOIN time_period ON booking.time_period_id = time_period.id 


WHERE 
  time_period.start_date  %(start_date_1)s 
  OR 
  time_period.end_date  %(end_date_1)s


With the following code : 




class
 Booking(BaseModel):
    


    
    using_options(tablename=booking)



    reprattr    =  time_period


   
 faces   = ManyToMany(Face)
    # A client has one and only one booking per time period


    time_period = ManyToOne(TimePeriod)
    


    @classmethod
    def
 get_available_faces(self,time_period):
    


    Return faces that are not booked during the given time_period.
    


    from timeperiod import TimePeriod
    from face   import Face


    
    start_date_cond = TimePeriod.start_date  time_period.end_date


    end_date_cond   = TimePeriod.end_date    time_period.start_date


    unbooked    = or_(start_date_cond,end_date_cond)



    # query = 
Face.query.filter(Face.bookings.any(Booking.time_period.has(unbooked)))


    # return query.all()



    query =
 Face.query.filter(unbooked)
    #return query.all()


    query = query.outerjoin(Face.bookings)
    #return query.all()


    query = query.join(Booking.time_period)
    return query.all()




And still not the expected results (it should return faces with no bookings at 
all but it doesen't).

Thanks for any help.

Y.Chaouche



--- On Wed, 10/13/10, chaouche yacine yacinechaou...@yahoo.com wrote:



From: chaouche yacine yacinechaou...@yahoo.com
Subject: Re: [sqlalchemy] Checking the availablity of a booked Item
To: sqlalchemy@googlegroups.com


Date: Wednesday, October 13, 2010, 5:25 AM

Thank you Thadeus, I believe
 Face.query.filter(filter_cond).outerjoin(join_clause).all() does a full 
outerjoin, or is there another way to do it ?

Y.Chaouche





--- On Wed, 10/13/10, Thadeus Burgess thade...@thadeusb.com wrote:



From: Thadeus Burgess thade...@thadeusb.com
Subject: Re: [sqlalchemy] Checking the availablity of a booked Item


To: sqlalchemy@googlegroups.com
Date: Wednesday, October 13, 2010, 12:04 AM

For outer joins you need a where clause on the joined tables.



http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html



Using a full outer join should return the expected results.
--
Thadeus





On Tue, Oct 12, 2010 at 1:41 PM, chaouche yacine yacinechaou...@yahoo.com 
wrote:




Hello,



Here's my simple model (For simplification, consider Face as a Billboard) :



+-+          +---+       +--+

|Face |..   |Campaign   |   ...|TimePeriod|

+-+      .   +---+   .   +--+

|code |      .   |time_period|   |start_time|

+-+      .   +---+       +--+

             |faces      |       |end_time  |

                 +---+       +--+



One way to read this model is : A campaign can book multiple faces during a 
certain period of time.



What I want to do is get all the available Faces for a given period of time, to 
see what faces can I book for a new campaign that longs for that particular 
period of time. I would typically have a Face.get_available(time_period) class 
method that does the job. This method would look for all the faces that don't 
have an ongoing booking. My question is : how to write such a method ?







Here's how I figured it out (couldn't get it to work) :



class Face(Entity):

    using_options(tablename=faces)

   �...@classmethod

    def get_available(self,time_period):

        

        Return faces that are not booked (not in any campaign

Re: [sqlalchemy] Checking the availablity of a booked Item

2010-10-14 Thread chaouche yacine
Here's the SQL I got : 

SELECT face.id AS face_id 
FROM face 
LEFT OUTER JOIN face_bookings__booking_faces AS face_bookings__booking_faces_1 
        ON face.id = face_bookings__booking_faces_1.face_id 
LEFT OUTER JOIN booking 
        ON booking.id = face_bookings__booking_faces_1.booking_id 
JOIN time_period ON booking.time_period_id = time_period.id 
WHERE 
  time_period.start_date  %(start_date_1)s 
  OR 
  time_period.end_date  %(end_date_1)s


With the following code : 


class Booking(BaseModel):
    
    
    using_options(tablename=booking)

    reprattr    =  time_period
    faces   = ManyToMany(Face)
    # A client has one and only one booking per time period
    time_period = ManyToOne(TimePeriod)
    
    @classmethod
    def get_available_faces(self,time_period):
    
    Return faces that are not booked during the given time_period.
    
    from timeperiod import TimePeriod
    from face   import Face
    
    start_date_cond = TimePeriod.start_date  time_period.end_date
    end_date_cond   = TimePeriod.end_date    time_period.start_date
    unbooked    = or_(start_date_cond,end_date_cond)

    # query = 
Face.query.filter(Face.bookings.any(Booking.time_period.has(unbooked)))
    # return query.all()

    query = Face.query.filter(unbooked)
    #return query.all()
    query = query.outerjoin(Face.bookings)
    #return query.all()
    query = query.join(Booking.time_period)
    return query.all()


And still not the expected results (it should return faces with no bookings at 
all but it doesen't).

Thanks for any help.

Y.Chaouche

--- On Wed, 10/13/10, chaouche yacine yacinechaou...@yahoo.com wrote:

From: chaouche yacine yacinechaou...@yahoo.com
Subject: Re: [sqlalchemy] Checking the availablity of a booked Item
To: sqlalchemy@googlegroups.com
Date: Wednesday, October 13, 2010, 5:25 AM

Thank you Thadeus, I believe 
Face.query.filter(filter_cond).outerjoin(join_clause).all() does a full 
outerjoin, or is there another way to do it ?

Y.Chaouche





--- On Wed, 10/13/10, Thadeus Burgess thade...@thadeusb.com wrote:

From: Thadeus Burgess thade...@thadeusb.com
Subject: Re: [sqlalchemy] Checking the availablity of a booked Item
To: sqlalchemy@googlegroups.com
Date: Wednesday, October 13, 2010, 12:04 AM

For outer joins you need a where clause on the joined tables.

http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html



Using a full outer join should return the expected results.
--
Thadeus





On Tue, Oct 12, 2010 at 1:41 PM, chaouche yacine yacinechaou...@yahoo.com 
wrote:


Hello,



Here's my simple model (For simplification, consider Face as a Billboard) :



+-+          +---+       +--+

|Face |..   |Campaign   |   ...|TimePeriod|

+-+      .   +---+   .   +--+

|code |      .   |time_period|   |start_time|

+-+      .   +---+       +--+

             |faces      |       |end_time  |

                 +---+       +--+



One way to read this model is : A campaign can book multiple faces during a 
certain period of time.



What I want to do is get all the available Faces for a given period of time, to 
see what faces can I book for a new campaign that longs for that particular 
period of time. I would typically have a Face.get_available(time_period) class 
method that does the job. This method would look for all the faces that don't 
have an ongoing booking. My question is : how to write such a method ?





Here's how I figured it out (couldn't get it to work) :



class Face(Entity):

    using_options(tablename=faces)

   �...@classmethod

    def get_available(self,time_period):

        

        Return faces that are not booked (not in any campaign) during the given 
time_period.

        

        # start_date_cond     = TimePeriod.start_date  time_period.end_date

        # end_date_cond       = TimePeriod.end_date    time_period.start_date

        # available_periods   = 
Campaign.time_period.has(or_(start_date_cond,end_date_cond))

        # unavailable_periods = not(available_periods)



        # I am pretty sure that the time conditions are good.

        # Here's a good way to convince yourself (read from bottom to top) :



        # L1                      
0---

        # L2 --|

        # L3 
0[]--



        # L3 represents the desired period (passed as argument) going from [ 
to ]

        # place the start date of the booked face anywhere on L2

        # place the end date of the booked face anywhere on L1

        # of course, end date must be after start date...

        # Anyway you do it, your face isn't available for the period of time in 
L3.



        start_date_cond

Re: [sqlalchemy] Checking the availablity of a booked Item

2010-10-14 Thread chaouche yacine
Here's the SQL I got : 

SELECT face.id AS face_id 
FROM face 
LEFT OUTER JOIN face_bookings__booking_faces AS face_bookings__booking_faces_1 
        ON face.id = face_bookings__booking_faces_1.face_id 
LEFT OUTER JOIN booking 
        ON booking.id = face_bookings__booking_faces_1.booking_id 
JOIN time_period ON booking.time_period_id = time_period.id 
WHERE 
  time_period.start_date  %(start_date_1)s 
  OR 
  time_period.end_date  %(end_date_1)s


With the following code : 


class Booking(BaseModel):
    
    
    using_options(tablename=booking)

    reprattr    =  time_period
    faces   = ManyToMany(Face)
    # A client has one and only one booking per time period
    time_period = ManyToOne(TimePeriod)
    
    @classmethod
    def get_available_faces(self,time_period):
    
    Return faces that are not booked during the given time_period.
    
    from timeperiod import TimePeriod
    from face   import Face
    
    start_date_cond = TimePeriod.start_date  time_period.end_date
    end_date_cond   = TimePeriod.end_date    time_period.start_date
    unbooked    = or_(start_date_cond,end_date_cond)

    # query = 
Face.query.filter(Face.bookings.any(Booking.time_period.has(unbooked)))
    # return query.all()

    query = Face.query.filter(unbooked)
    #return query.all()
    query = query.outerjoin(Face.bookings)
    #return query.all()
    query = query.join(Booking.time_period)
    return query.all()


And still not the expected results (it should return faces with no bookings at 
all but it doesen't).

Thanks for any help.

Y.Chaouche

--- On Wed, 10/13/10, chaouche yacine yacinechaou...@yahoo.com wrote:

From: chaouche yacine yacinechaou...@yahoo.com
Subject: Re: [sqlalchemy] Checking the availablity of a booked Item
To: sqlalchemy@googlegroups.com
Date: Wednesday, October 13, 2010, 5:25 AM

Thank you Thadeus, I believe 
Face.query.filter(filter_cond).outerjoin(join_clause).all() does a full 
outerjoin, or is there another way to do it ?

Y.Chaouche





--- On Wed, 10/13/10, Thadeus Burgess thade...@thadeusb.com wrote:

From: Thadeus Burgess thade...@thadeusb.com
Subject: Re: [sqlalchemy] Checking the availablity of a booked Item
To: sqlalchemy@googlegroups.com
Date: Wednesday, October 13, 2010, 12:04 AM

For outer joins you need a where clause on the joined tables.

http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html



Using a full outer join should return the expected results.
--
Thadeus





On Tue, Oct 12, 2010 at 1:41 PM, chaouche yacine yacinechaou...@yahoo.com 
wrote:


Hello,



Here's my simple model (For simplification, consider Face as a Billboard) :



+-+          +---+       +--+

|Face |..   |Campaign   |   ...|TimePeriod|

+-+      .   +---+   .   +--+

|code |      .   |time_period|   |start_time|

+-+      .   +---+       +--+

             |faces      |       |end_time  |

                 +---+       +--+



One way to read this model is : A campaign can book multiple faces during a 
certain period of time.



What I want to do is get all the available Faces for a given period of time, to 
see what faces can I book for a new campaign that longs for that particular 
period of time. I would typically have a Face.get_available(time_period) class 
method that does the job. This method would look for all the faces that don't 
have an ongoing booking. My question is : how to write such a method ?





Here's how I figured it out (couldn't get it to work) :



class Face(Entity):

    using_options(tablename=faces)

   �...@classmethod

    def get_available(self,time_period):

        

        Return faces that are not booked (not in any campaign) during the given 
time_period.

        

        # start_date_cond     = TimePeriod.start_date  time_period.end_date

        # end_date_cond       = TimePeriod.end_date    time_period.start_date

        # available_periods   = 
Campaign.time_period.has(or_(start_date_cond,end_date_cond))

        # unavailable_periods = not(available_periods)



        # I am pretty sure that the time conditions are good.

        # Here's a good way to convince yourself (read from bottom to top) :



        # L1                      
0---

        # L2 --|

        # L3 
0[]--



        # L3 represents the desired period (passed as argument) going from [ 
to ]

        # place the start date of the booked face anywhere on L2

        # place the end date of the booked face anywhere on L1

        # of course, end date must be after start date...

        # Anyway you do it, your face isn't available for the period of time in 
L3.



        start_date_cond

Re: [sqlalchemy] Checking the availablity of a booked Item

2010-10-13 Thread chaouche yacine
Thank you Thadeus, I believe 
Face.query.filter(filter_cond).outerjoin(join_clause).all() does a full 
outerjoin, or is there another way to do it ?

Y.Chaouche





--- On Wed, 10/13/10, Thadeus Burgess thade...@thadeusb.com wrote:

From: Thadeus Burgess thade...@thadeusb.com
Subject: Re: [sqlalchemy] Checking the availablity of a booked Item
To: sqlalchemy@googlegroups.com
Date: Wednesday, October 13, 2010, 12:04 AM

For outer joins you need a where clause on the joined tables.

http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html



Using a full outer join should return the expected results.
--
Thadeus





On Tue, Oct 12, 2010 at 1:41 PM, chaouche yacine yacinechaou...@yahoo.com 
wrote:


Hello,



Here's my simple model (For simplification, consider Face as a Billboard) :



+-+          +---+       +--+

|Face |..   |Campaign   |   ...|TimePeriod|

+-+      .   +---+   .   +--+

|code |      .   |time_period|   |start_time|

+-+      .   +---+       +--+

             |faces      |       |end_time  |

                 +---+       +--+



One way to read this model is : A campaign can book multiple faces during a 
certain period of time.



What I want to do is get all the available Faces for a given period of time, to 
see what faces can I book for a new campaign that longs for that particular 
period of time. I would typically have a Face.get_available(time_period) class 
method that does the job. This method would look for all the faces that don't 
have an ongoing booking. My question is : how to write such a method ?





Here's how I figured it out (couldn't get it to work) :



class Face(Entity):

    using_options(tablename=faces)

   �...@classmethod

    def get_available(self,time_period):

        

        Return faces that are not booked (not in any campaign) during the given 
time_period.

        

        # start_date_cond     = TimePeriod.start_date  time_period.end_date

        # end_date_cond       = TimePeriod.end_date    time_period.start_date

        # available_periods   = 
Campaign.time_period.has(or_(start_date_cond,end_date_cond))

        # unavailable_periods = not(available_periods)



        # I am pretty sure that the time conditions are good.

        # Here's a good way to convince yourself (read from bottom to top) :



        # L1                      
0---

        # L2 --|

        # L3 
0[]--



        # L3 represents the desired period (passed as argument) going from [ 
to ]

        # place the start date of the booked face anywhere on L2

        # place the end date of the booked face anywhere on L1

        # of course, end date must be after start date...

        # Anyway you do it, your face isn't available for the period of time in 
L3.



        start_date_cond     = TimePeriod.start_date = time_period.end_date

        end_date_cond       = TimePeriod.end_date   = time_period.start_date

        unavailable_periods = 
Campaign.time_period.has(and_(start_date_cond,end_date_cond))

        # I am not sure about what follows...

        filter_cond         = not_(unavailable_periods)

        join_clause         = Campaign.faces



        return Face.query.filter(filter_cond).outerjoin(join_clause).all()





This code returns only faces that have already been booked before or have a 
future booking, and are free for the moment. But faces with no bookings at all 
are not returned. This may be due to an incorrect outerjoin ? (I also tried a 
simple join with no success)





Here's the generated sql for one query :



2010-10-12 19:34:22,837 INFO sqlalchemy.engine.base.Engine.0x...f4ec

SELECT faces.id AS faces_id

FROM campaigns LEFT OUTER JOIN campaigns_faces__faces AS 
campaigns_faces__faces_1 ON campaigns.id = campaigns_faces__faces_1.campaigns_id

LEFT OUTER JOIN faces ON faces.id = campaigns_faces__faces_1.faces_id

WHERE NOT (EXISTS (SELECT 1

                  FROM time_periods

                  WHERE campaigns.time_period_id = time_periods.id

                  AND time_periods.start_date = %(start_date_1)s

                  AND time_periods.end_date = %(end_date_1)s))



2010-10-12 19:34:22,837 INFO sqlalchemy.engine.base.Engine.0x...f4ec 
{'start_date_1': datetime.date(2010, 10, 30), 'end_date_1': datetime.date(2010, 
10, 20)}

[Face id=1 at 0x932218c  ]





Any help would be very appreciated.



Y.Chaouche



PS : and please, don't give me that lame it's elixir excuse. The question is 
about how to construct the proper query for the desired operation in a 
sqlalchemy way. Elixir is only another Declarative approach + mapping, that's 
it.











--

You received this message because you are subscribed to the Google Groups 
sqlalchemy group.

To post to this group, send

[sqlalchemy] Checking the availablity of a booked Item

2010-10-12 Thread chaouche yacine
Hello,

Here's my simple model (For simplification, consider Face as a Billboard) :

+-+  +---+   +--+
|Face |..   |Campaign   |   ...|TimePeriod|
+-+  .   +---+   .   +--+
|code |  .   |time_period|   |start_time|
+-+  .   +---+   +--+
 |faces  |   |end_time  |
 +---+   +--+

One way to read this model is : A campaign can book multiple faces during a 
certain period of time.

What I want to do is get all the available Faces for a given period of time, to 
see what faces can I book for a new campaign that longs for that particular 
period of time. I would typically have a Face.get_available(time_period) class 
method that does the job. This method would look for all the faces that don't 
have an ongoing booking. My question is : how to write such a method ? 

Here's how I figured it out (couldn't get it to work) :

class Face(Entity):
using_options(tablename=faces)
@classmethod
def get_available(self,time_period):

Return faces that are not booked (not in any campaign) during the given 
time_period.

# start_date_cond = TimePeriod.start_date  time_period.end_date
# end_date_cond   = TimePeriod.end_datetime_period.start_date
# available_periods   = 
Campaign.time_period.has(or_(start_date_cond,end_date_cond))
# unavailable_periods = not(available_periods)

# I am pretty sure that the time conditions are good.
# Here's a good way to convince yourself (read from bottom to top) :

# L1  
0---
# L2 --|
# L3 
0[]--

# L3 represents the desired period (passed as argument) going from [ 
to ]
# place the start date of the booked face anywhere on L2
# place the end date of the booked face anywhere on L1
# of course, end date must be after start date...
# Anyway you do it, your face isn't available for the period of time in 
L3. 

start_date_cond = TimePeriod.start_date = time_period.end_date
end_date_cond   = TimePeriod.end_date   = time_period.start_date
unavailable_periods = 
Campaign.time_period.has(and_(start_date_cond,end_date_cond))
# I am not sure about what follows...
filter_cond = not_(unavailable_periods)
join_clause = Campaign.faces

return Face.query.filter(filter_cond).outerjoin(join_clause).all()


This code returns only faces that have already been booked before or have a 
future booking, and are free for the moment. But faces with no bookings at all 
are not returned. This may be due to an incorrect outerjoin ? (I also tried a 
simple join with no success)

Here's the generated sql for one query : 

2010-10-12 19:34:22,837 INFO sqlalchemy.engine.base.Engine.0x...f4ec 
SELECT faces.id AS faces_id 
FROM campaigns LEFT OUTER JOIN campaigns_faces__faces AS 
campaigns_faces__faces_1 ON campaigns.id = 
campaigns_faces__faces_1.campaigns_id 
LEFT OUTER JOIN faces ON faces.id = campaigns_faces__faces_1.faces_id 
WHERE NOT (EXISTS (SELECT 1 
  FROM time_periods 
  WHERE campaigns.time_period_id = time_periods.id 
  AND time_periods.start_date = %(start_date_1)s 
  AND time_periods.end_date = %(end_date_1)s))

2010-10-12 19:34:22,837 INFO sqlalchemy.engine.base.Engine.0x...f4ec 
{'start_date_1': datetime.date(2010, 10, 30), 'end_date_1': datetime.date(2010, 
10, 20)}
[Face id=1 at 0x932218c  ]


Any help would be very appreciated.

Y.Chaouche

PS : and please, don't give me that lame it's elixir excuse. The question is 
about how to construct the proper query for the desired operation in a 
sqlalchemy way. Elixir is only another Declarative approach + mapping, that's 
it.


  

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@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.

# ORM
from sqlalchemy.sql.expression import * 
from sqlalchemy.ormimport reconstructor
from elixirimport *
# stdlib
from datetime  import date
import sys

class TimePeriod(Entity):


using_options(tablename=time_periods)

start_date = Field(Date())
end_date   = Field(Date())
name   = Field(Unicode())

class Campaign(Entity):
using_options(tablename=campaigns)
time_period = ManyToOne(TimePeriod)
faces   = ManyToMany(Face)

class Face(Entity):

Re: [sqlalchemy] Copying instances from old to new schema DB

2010-09-12 Thread chaouche yacine
The two instances don't have the same ID, the uniqueness is tested on two other 
columns. 

 session.query(cls).filter(cls.the_unique_column==new_object.the_unique_column).first()

Is there a way to get the tuple (usually a couple) of columns that are involved 
in a unique constraint ? if there is such a way, than the line of code above 
could be generically applied to all models, which would be sweet :)

something like : 

for row in csv:
new_object = make_an_object_from_csv_row(row)
existing_object = get_existing_object(new_object)
if existing_object is not None:
new_object.id = existing_object.id
new_object = session.merge(new_object)
session.commit()

def get_existing_object(new_object):

unique_constraints = [constraint.columns for constraint in 
cls.get_constraints() 
  if constraint.get_type() == UniqueConstraint]

u_c_columns = [constraint.columns for constraint in unique_constraints]

query = session.query(cls)
for column_tuples in u_c_columns :
for column in column_tuples : 
query = query.filter(cls.get_attr(column) == 
new_object.get_attr(column))

return query.first()


--- On Thu, 9/9/10, Michael Bayer mike...@zzzcomputing.com wrote:

 From: Michael Bayer mike...@zzzcomputing.com
 Subject: Re: [sqlalchemy] Copying instances from old to new schema DB
 To: sqlalchemy@googlegroups.com
 Date: Thursday, September 9, 2010, 9:54 AM
 
 On Sep 9, 2010, at 11:31 AM, chaouche yacine wrote:
 
  Thank you Michael, that's for the catch-the-error
 part. How about the set-relations-right part, if I decided
 to go with my fix-as-you go recipe ? do you have any idea ?
 the dictionary approach seems good, but I still am curious
 about how to set relations generically on models. I think
 I'll use it somewhere else in my code.
 
 You don't need to set any relations.   If
 your new B has a fully populated primary key, you should
 just be using session.merge() for the whole thing. 
   This can work with your integrity error scheme, or
 more simply with the select first schemes below:
 
 
 for row in csv:
     new_object =
 make_an_object_from_csv_row(row)
     new_object = session.merge(new_object)
 session.commit()
 
 
 if new_object does *not* have the correct primary key,
 then:
 
 for row in csv:
     new_object =
 make_an_object_from_csv_row(row)
     existing_object =
 session.query(cls).filter(cls.the_unique_column==new_object.the_unique_column).first()
     if existing_object is not None:
         new_object.id =
 existing_object.id
     new_object = session.merge(new_object)
 session.commit()
 
 
 if you don't like the many indvidual SELECT statements,
 then
 
 # load a dictionary of (unique attr, primary key)
 lookup = dict(
     session.query(cls.the_unique_column,
 cls.id)
 )
 for row in csv:
     new_object =
 make_an_object_from_csv_row(row)
         if new_object.the_unique_column
 in lookup:
             new_object.id =
 lookup[new_object.the_unique_column]
     new_object = session.merge(new_object)
 session.commit()
 
 or if most of your rows are replacement rows, quicker to
 preload everything:
 
 
 # load a dictionary of (unique attr, instance)
 lookup = dict(
     session.query(cls.the_unique_column,
 cls)
 )
 for row in csv:
     new_object =
 make_an_object_from_csv_row(row)
         if new_object.the_unique_column
 in lookup:
             new_object.id =
 lookup[new_object.the_unique_column].id
     new_object = session.merge(new_object)
 session.commit()
 
 
 
 
 
  
  By the way, I think the pseudo should have been : 
  
  instance = next_instance_from_csv()
  try:
     session.commit()
  except IntegrityError,e :
     session.rollback()
     if e.orig == UniqueConstraintError : 
         original_instance =
 ModelClass.get(instance.id)
         for relation_name in
 instance.get_relation_names() :
             # Is this
 correct ?
            
 path_to_attribute= mapper.+ relation +.inverse # I don't
 know where to find this ?
            
 instance.set_attribute(path_to_attribute,original_instance)
         session.commit()
  
  class BaseModel (DeclarativeBase):
     ...
     def set_attribute(self,path,value):
         nodes     
   = path.explode(.)
         current_node = self
         for next_node in nodes :
             current_node
 = getattr(current_node,next_node,None)
             if not
 current_node:
                
 raise InvalidAttribute
        
 set_attribute(current_node,value) # sqla's set_attribute,
 for whatever reason... 
  
  
  Y.Chaouche
  
  
  --- On Thu, 9/9/10, Michael Bayer mike...@zzzcomputing.com
 wrote:
  
  From: Michael Bayer mike...@zzzcomputing.com
  Subject: Re: [sqlalchemy] Copying instances from
 old to new schema DB
  To: sqlalchemy@googlegroups.com
  Date: Thursday, September 9, 2010, 5:59 AM
  
  On Sep 9, 2010, at 6:31 AM, chaouche yacine
 wrote:
  
  Hello list,
  
  My schema has changed, and now I want to
 retrieve my
  old data (of the old schema

Re: [sqlalchemy] Copying instances from old to new schema DB

2010-09-09 Thread chaouche yacine
Thank you Michael, that's for the catch-the-error part. How about the 
set-relations-right part, if I decided to go with my fix-as-you go recipe ? do 
you have any idea ? the dictionary approach seems good, but I still am curious 
about how to set relations generically on models. I think I'll use it somewhere 
else in my code.

By the way, I think the pseudo should have been : 

instance = next_instance_from_csv()
try:
session.commit()
except IntegrityError,e :
session.rollback()
if e.orig == UniqueConstraintError : 
original_instance = ModelClass.get(instance.id)
for relation_name in instance.get_relation_names() :
# Is this correct ?
path_to_attribute= mapper.+ relation +.inverse # I don't know 
where to find this ?
instance.set_attribute(path_to_attribute,original_instance)
session.commit()

class BaseModel (DeclarativeBase):
...
def set_attribute(self,path,value):
nodes= path.explode(.)
current_node = self
for next_node in nodes :
current_node = getattr(current_node,next_node,None)
if not current_node:
raise InvalidAttribute
set_attribute(current_node,value) # sqla's set_attribute, for whatever 
reason... 


Y.Chaouche


--- On Thu, 9/9/10, Michael Bayer mike...@zzzcomputing.com wrote:

 From: Michael Bayer mike...@zzzcomputing.com
 Subject: Re: [sqlalchemy] Copying instances from old to new schema DB
 To: sqlalchemy@googlegroups.com
 Date: Thursday, September 9, 2010, 5:59 AM
 
 On Sep 9, 2010, at 6:31 AM, chaouche yacine wrote:
 
  Hello list,
  
  My schema has changed, and now I want to retrieve my
 old data (of the old schema) to the new database (with the
 new schema) from csv files (I export the tables of the old
 database to csv files and then load those csv files to the
 new database with some column mapping and some gap filling
 for new columns)
  
  The problem is that my new schema have a
 UniqueConstraint for some tables (like : the name column of
 the city table should be unique within a country). This
 constraint was not present in the old schema and data is
 corrupt (two cities with the same name in the same country).
 So when I try to insert them in the new database, I have
 IntegrityErrors. 
  
  The solution I thought of was :
  * Catch the IntegrityError exception 
  * If it's a problem on a UniqueConstraint, then the
 exception was raised because I tried to insert instance B
 that has the same key as instance A that was inserted
 before.
  * So for all children of B (B's relations), set their
 parent to A. For example, for all citizens of B, set their
 city to A, beause A and B ought to be the same. 
  * Then, safely ignore B and move on to the next
 instance.
  
  Here's what has been done so far (that works, I just
 use psuedo code for illustration purpose. If necessary,
 you can look at the actual attached source files): 
  
  line       =
 csvloader.next_row()
  ModelClass = get_current_model()
  instance   =
 ModelClass.create_instance(**(to_dict(line)))
  session.add(instance) 
  
  I wish I could do something like this : 
  try:    
     session.commit()
  except IntegrityError,e : 
     session.rollback()
     errror = get_error()
     if type_of(error) ==
 UniqueConstraintError :
         original_instance =
 ModelClass.get(instance.id)
         for relation in
 instance.get_relations() : 
             # Is this
 correct ? 
         
 instance.relation.inverse = original_instance
         session.commit()
  
  My questions are : how to write get_error, type_of,
 where to get UniqueContraintError, how to write
 get_relations, how to set the inverse of a relation (is
 instance.realtion.inverse the right thing to set ?) and is
 this approach correct ?
 
 There's no portable way to detect unique constraint
 errors across DBAPIs, you'd have to catch the specific error
 that you've observed your DBAPI emits as well as the
 message/codes contained within it, and code against
 that.   SQLAlchemy wraps DBAPI exceptions in
 its own same-named wrapper and the object emitted by the
 DBAPI is available under the .orig member.
 
 One improvement to the recipe would be if you used
 savepoints, if supported by your database, so that when you
 issue rollback() inside a savepoint block, the whole
 transaction isn't rolled back and you can maintain the whole
 operation in one transaction.   The session
 can start a savepoint using begin_nested().
 
 When I do csv loads like these however I usually load the
 full list of identifiers to be checked into memory ahead of
 time.  If the csv is less than 100K rows and represents
 the full table of data, I just load the whole thing into a
 dictionary, formatted according to whatever these are the
 fields that are unique I'm dealing with, and consult the
 dictionary as I go along.    Otherwise, I load
 individual blocks of data in as I scan through portions of
 the csv (like, give me all

[sqlalchemy] update a relation from its id

2010-09-02 Thread chaouche yacine
Hello group,

Suppose A has a ManyToOne relation to B (A is a child of B). I want to perform 
something like : 
a.b_id = b.id
assert a.b == b

How do I do this in sqlalchemy ? 

The following attempt failed 

---


from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base

session= sessionmaker()()
Base   = declarative_base()
metadata   = Base.metadata
metadata.bind  = postgres://somedb

class SQLModel:
reprattr = name
def __repr__(self):

Will a return string of the form SomeModel fieldn=filedn value...  
id = 1

if type(self.reprattr) != list :
self.reprattr = [self.reprattr]
attrstr =   .join([%s=\%s\ % (attr, getattr(self,attr))
 for attr in self.reprattr 
 if hasattr(self,attr)
 ]
)
reprstr = %s id=%s at 0x%x %s  % (self.__class__.__name__, 
self.id,id(self),attrstr)
return reprstr

class Country (Base, SQLModel):
Creates a Country Object.
__tablename__ = countries
id= Column(Integer, primary_key=True)
name  = Column(String, nullable=False)


class City (Base, SQLModel):
Creates a City Object.
__tablename__ = cities
id = Column(Integer, primary_key=True)
country_id = Column(Integer, ForeignKey(countries.id, 
ondelete=RESTRICT))
name   = Column(String, nullable=False)
country= relation(Country, backref=cities)

metadata.drop_all()
metadata.create_all()

algiers = City(name=Algiers)
algeria = Country(name=Algeria)
session.add_all([algiers,algeria])
session.flush()
algiers.country_id = algeria
session.flush()
print algiers.country
#  None


Any help appreciated. 

Y.Chaouche


  

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@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] how to change a database

2009-12-03 Thread chaouche yacine
Why not create a different engine for that database ?

--- On Thu, 12/3/09, Peter vm...@mycircuit.org wrote:

 From: Peter vm...@mycircuit.org
 Subject: [sqlalchemy] how to change a database
 To: sqlalchemy@googlegroups.com
 Date: Thursday, December 3, 2009, 4:37 AM
 Hi
 
 Lets suppose I created an engine on database 'foo' and I
 want to create 
 a database 'bar' and then do my work on 'bar'.
 What is the recommended way to do this ?
 
 connection.execute('CREATE DATABASE IF NOT EXISTS bar')
 connection.execute('USE bar')
 
 The former command succeeds with a warning ( already
 discussed on this 
 list ) but the latter seems to be the wrong approach:
 
 ...
 2009-12-03 13:28:39,221 INFO
 sqlalchemy.engine.base.Engine.0x...b0ec COMMIT
 TypeError: 'NoneType' object is not callable in
 function lambda at 
 0x8821bc4 ignored
 
 
 Thanks a lot for your advice
 Peter
 
 --
 
 You received this message because you are subscribed to the
 Google Groups sqlalchemy group.
 To post to this group, send email to sqlalch...@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 sqlalch...@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] get_or_create(**kwargs) ?

2009-11-23 Thread chaouche yacine


--- On Sun, 11/22/09, Conor conor.edward.da...@gmail.com wrote:

 There is a problem with your code when the tag is in the
 cache: if the
 tag is added to the session via session.add or a relation
 add cascade,
 SQLAlchemy will try to INSERT the tag into the database on
 the next
 flush. 
 -Conor

I don't know, it seems not. I created a new empty Tags table, I create a new 
Pylons tag, and it creates it only on the first flush. If I add it a second 
time to the session, and reflush it, it won't try to re-insert it in the db. 
Here's my ipython session : 

In [1]: from someproject.model.tag import *

In [2]: setup_all()

In [3]: create_all()
12:59:34,878 INFO  [sqlalchemy.engine.base.Engine.0x...6fec] SHOW VARIABLES 
LIKE 'sql_mode'
12:59:34,882 INFO  [sqlalchemy.engine.base.Engine.0x...6fec] ()
12:59:34,886 INFO  [sqlalchemy.engine.base.Engine.0x...6fec] DESCRIBE `Tags`
12:59:34,886 INFO  [sqlalchemy.engine.base.Engine.0x...6fec] ()
12:59:34,888 INFO  [sqlalchemy.engine.base.Engine.0x...6fec] ROLLBACK
12:59:34,889 INFO  [sqlalchemy.engine.base.Engine.0x...6fec] 
CREATE TABLE `Tags` (
id INTEGER NOT NULL AUTO_INCREMENT, 
name VARCHAR(64), 
PRIMARY KEY (id)
)


12:59:34,907 INFO  [sqlalchemy.engine.base.Engine.0x...6fec] ()
12:59:34,959 INFO  [sqlalchemy.engine.base.Engine.0x...6fec] COMMIT

In [4]: pylons = Tag(Pylons)
12:59:59,171 INFO  [sqlalchemy.engine.base.Engine.0x...6fec] BEGIN
/home/chaouche/PYTHONENV/lib/python2.6/site-packages/SQLAlchemy-0.5.5-py2.6.egg/sqlalchemy/engine/default.py:230:
 SAWarning: Unicode type received non-unicode bind param value 'Pylons'
  param.append(processors[key](compiled_params[key]))
12:59:59,172 INFO  [sqlalchemy.engine.base.Engine.0x...6fec] SELECT `Tags`.id 
AS `Tags_id`, `Tags`.name AS `Tags_name` 
FROM `Tags` 
WHERE `Tags`.name = %s 
 LIMIT 0, 1
12:59:59,172 INFO  [sqlalchemy.engine.base.Engine.0x...6fec] ['Pylons']
not in the database

In [5]: pylons = Tag(Pylons)

In [6]: session.add(pylons)

In [7]: session.flush
Out[7]: bound method ScopedSession.do of sqlalchemy.orm.scoping.ScopedSession 
object at 0x98572ac

In [8]: session.flush()
13:00:14,116 INFO  [sqlalchemy.engine.base.Engine.0x...6fec] INSERT INTO `Tags` 
(name) VALUES (%s)
13:00:14,116 INFO  [sqlalchemy.engine.base.Engine.0x...6fec] ['Pylons']

In [9]: session.add(pylons)

In [10]: session.flush()

In [11]: pylons = Tag(Pylons)

In [12]: pylons
Out[12]: Tag Pylons

In [13]: session.add
session.add  session.add_all  

In [13]: session.add(pylons)

In [14]: session.flush()

In [15]: 



  

--

You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@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=.




Re: [sqlalchemy] get_or_create(**kwargs) ?

2009-11-22 Thread chaouche yacine
--- On Fri, 11/20/09, Conor conor.edward.da...@gmail.com wrote:

 
 Also, there is a recipe that looks for a matching object in
 the session
 before querying the database:
 http://www.sqlalchemy.org/trac/wiki/UsageRecipes/UniqueObject
 
 -Conor
 

Thank you Conor for you useful pointer. I have used this recipe and changed a 
little bit to use beaker as a caching mechanism with a memcached backend. So 
here's how it looks like :

from elixir import Entity, EntityMeta,setup_all,create_all,metadata
from pylons import cache

class MetaTag(EntityMeta):
cache = cache.get_cache(tags,type=memory)
def __call__(cls,name):

If it's in the cache, return the cached version
If not in the cache :
If it's in the database, retrieve it, cache it and return it
If it's not there, create it, cache it and return it

theTag = MetaTag.cache.get_value(key=name,createfunc=lambda:None)
if not theTag :
#not in the cache
theTag = cls.query.filter_by(name=name).first()
if not theTag:
#not in the database either
print not in the database
theTag = type.__call__(cls,name)
session.add(theTag)
#Adding it to the cache, after creating it in the database if it 
wasn't there
MetaTag.cache.set_value(key=name,value=theTag)
return theTag

class Tag(Entity):
__metaclass__ = MetaTag
using_options (tablename=Tags)
name   = Field(Unicode(64))

def __init__(self,name,*args,**kw):
Entity.__init__(self,*args,**kw)
self.name = name

def __repr__(self):
return Tag %s %  self.name

metadata.bind = mysql://username:passw...@localhost:3306/db
metadata.bind.echo = True

setup_all()
create_all()

And here's how it plays on the interpreter (ipython) :
Alger is already in the database, Constantine is not. I find the metaclass 
approach very API-friendly.

...

In [4]: Tag(Alger)
21:38:21,328 INFO  [sqlalchemy.engine.base.Engine.0x...2fec] BEGIN
/home/chaouche/PYTHONENV/lib/python2.6/site-packages/SQLAlchemy-0.5.5-py2.6.egg/sqlalchemy/engine/default.py:230:
 SAWarning: Unicode type received non-unicode bind param value 'Alger'
  param.append(processors[key](compiled_params[key]))
21:38:21,382 INFO  [sqlalchemy.engine.base.Engine.0x...2fec] SELECT `Tags`.id 
AS `Tags_id`, `Tags`.name AS `Tags_name` 
FROM `Tags` 
WHERE `Tags`.name = %s 
 LIMIT 0, 1
21:38:21,382 INFO  [sqlalchemy.engine.base.Engine.0x...2fec] ['Alger']
Out[4]: Tag Alger

In [5]: Tag(Alger)
Out[5]: Tag Alger

In [8]: Tag(Constantine)
/home/chaouche/PYTHONENV/lib/python2.6/site-packages/SQLAlchemy-0.5.5-py2.6.egg/sqlalchemy/engine/default.py:230:
 SAWarning: Unicode type received non-unicode bind param value 'Constantine'
  param.append(processors[key](compiled_params[key]))
21:39:17,487 INFO  [sqlalchemy.engine.base.Engine.0x...2fec] SELECT `Tags`.id 
AS `Tags_id`, `Tags`.name AS `Tags_name` 
FROM `Tags` 
WHERE `Tags`.name = %s 
 LIMIT 0, 1
21:39:17,487 INFO  [sqlalchemy.engine.base.Engine.0x...2fec] ['Constantine']
not in the database
Out[8]: Tag Constantine

In [9]: Tag(Constantine)
Out[9]: Tag Constantine

Any comments are very appreciated.

Y.Chaouche



  

--

You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@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=.




[sqlalchemy] get_or_create(**kwargs) ?

2009-11-20 Thread chaouche yacine
Hello,

This is the first time I try an ORM, and I chose SQLAlchemy, which is popular 
amongst pythonistas.

Since I am a complete beginner, here's my beginner's two cents question :

Suppose you have a very basic model like this (pseudo code) : 

User(firstname,lastname,nick,ManyToOne(city))
City(name)

Suppose I want to add a new user: 

user = User(John,Doe,jd, WhatToPutHere ?)

I whish I could write something like this :

user = User(John,Doe,jd, City(New Jersey))

Where City will first fetch for a city named New Jersey in the database and 
return it if it exists, or create a new one (in the database) and return it.

So I thought maybe I could have a helper function like this : 

def city(name):
return City.query.filter_by(name=name).first() or City(name=name)


and then : 

user = User(John,Doe,jd,city(New Jersey))

But how can I be sure that the city of New Jersey will be inserted before the 
user in the database so that the new user row will get the proper city id ?

So I figured to rewrite the city helper function like this :

def city(name):
theCity = City.query.filter_by(name=name).first()
if not theCity :
   theCity = City(name=name)
   session.commit() # to be sure it will be inserted before the user
return theCity

In the videostore example I saw an interresting use of the @classmethod 
decorator, which may be useful to define city as a static method of the City 
class.

I need your advice. Is this a good way to tackle to problem ? how does your 
code look like ?

Y.Chaouche


  

--

You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@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=.