On Apr 10, 2010, at 12:28 PM, DrLongGhost wrote: > I have a couple questions regarding the best way to do date math in > SQLAlchemy with Postgresql and how I can write fixture-based unit > tests for this without requiring an actual database in my test. > > There's 2 specific types of dates which I need to be retrieving. > Written in SQL these would be: > 1) CURRENT_TIMESTAMP > 2) CURRENT_TIMESTAMP + interval 'X months' > > I know that I can use sqlalchemy.func.current_timestamp() to retrieve > the first, but this breaks when I try to unit test it and there is no > database session present. For example, consider the following code: > > @property > def is_active(self): > return ((not self.date_closed) or > (self.date_closed >= sa.func.current_timestamp()))
the above code may return a python boolean, or may return a SQL expression. I don't see how the above code actually accomplishes something useful - "func.current_timestamp()" doesn't execute against the database in any case, unless the return value of is_active() is used in a flush(), in which case its only evaluated on the database side, and you only see its result if you then re-SELECT the value (which the Session would do for you, when the expired attribute is accessed). Your unit tests couldn't possibly rely upon flush() and then re-fetching expired attributes if they also require no database to be present. If you're actually trying to simulate full roundtrips to your database and back without a database in use, that doesn't make much sense. I'd just run my unit tests against a Postgresql database intended for tests, if indeed you're looking for functionality that occurs via round trips through flush and back - thats how this is normally done. The level of mocking needed to "simulate" that would render your unit tests as not really testing what actually occurs in your application. > One idea my boss suggested was to use the Fudge > module in my tests to overload sqlalchemy.func.current_timestamp() > with a function that uses python's datetime module to return the > current timestamp. Thus, when run in production, my code will use the > database to get the current time, but when run in a unit test, we > avoid a broken test by instead using python's datetime to get the > current timestamp. You could just use a function "my_current_timestamp" which your test suite can mock to return a datetime instead of a SQL expression. But I don't see this approach working for anything beyond the most small and trivial cases. > Does anyone have any experience or examples of this type of approach? > > Also, while this seems like it will work for getting the current time, > how would I use the same approach to get "CURRENT_TIMESTAMP + interval > 'X months'"? I don't see a pre-written > "sqlalchemy.func.current_timestamp_plus_interval('X months') to get a SQL expression like that, call func.current_timestamp() + datetime.interval(days=60) (note that you can't specify intervals in terms of months since a "month" is not a fixed unit of time). Defintiely use 0.6 for such expressions as many improvements have been made to PG date arithmetic in 0.6. If you were using "my_current_timestamp" as an abstraction from func.current_timestamp(), it would work both as a SQL expression and as an all-Python expression. See examples/derived_attributes/ in the distro for a little exploration on that concept. -- 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.