Reputation: 75
I need to execute a query which compares only the year and month value from TIMESTAMP column where the records look like this:
2015-01-01 08:33:06
The SQL Query is very simple (the interesting part is the year(timestamp) and month(timestamp) which extracts the year and the month so I can use them for comparison:
SELECT model, COUNT(model) AS count
FROM log.logs
WHERE SOURCE = "WEB"
AND year(timestamp) = 2015
AND month(timestamp) = 01
AND account = "TEST"
AND brand = "Nokia"
GROUP BY model
ORDER BY count DESC limit 10
Now the problem:
This is my SQLAlchemy Query:
devices = (db.session.query(Logs.model, Logs.timestamp,
func.count(Logs.model).label('count'))
.filter_by(source=str(source))
.filter_by(account=str(acc))
.filter_by(brand=str(brand))
.filter_by(year=year)
.filter_by(month=month)
.group_by(Logs.model)
.order_by(func.count(Logs.model).desc()).all())
The part:
.filter_by(year=year)
.filter_by(month=month)
is not the same as
AND year(timestamp) = 2015
AND month(timestamp) = 01
and my SQLAchemy query is not working. It seems like year and month are MySQL functions that extract the values from a timestamp column.
My DB Model looks like this:
class Logs(db.Model):
id = db.Column(db.Integer, primary_key=True)
timestamp = db.Column(db.TIMESTAMP, primary_key=False)
.... other attributes
It is interesting to mention that when I select and print Logs.timestamp
it is in the following format:
(datetime.datetime(2013, 7, 11, 12, 47, 28))
How should this part be written in SQLAlchemy if I want my SQLAlchemy query to compare by the DB Timestamp year and month ?
.filter_by(year=year) #MySQL - year(timestamp)
.filter_by(month=month) #MySQL- month(timestamp)
I tried .filter(Logs.timestamp == year(timestamp)
and similar variations but no luck. Any help will be greatly appreciated.
Upvotes: 2
Views: 4787
Reputation: 3947
You can use custom constructs if you want to use functions that are specific to your database, like the year
function you mention for MySQL
. However I don't use MySQL
and cannot give you some tested code (I did not even know about this function, by the way).
This would be an simple and useless example for Oracle (which is tested). I hope from this one you can quite easily deduce yours.
from sqlalchemy.sql import expression
from sqlalchemy.ext.compiler import compiles
from sqlalchemy import Date
class get_current_date(expression.FunctionElement):
type = Date()
@compiles(get_current_date, 'oracle')
def ora_get_current_date(element, compiler, **kw):
return "CURRENT_DATE"
session = schema_mgr.get_session()
q = session.query(sch.Tweet).filter(sch.Tweet.created_at == get_current_date())
tweets_today = pd.read_sql(q.statement, session.bind)
However I don't need to mention that this way you make your highly portable SQLAlchemy
code a bit less portable.
Hope it helps.
Upvotes: 0
Reputation: 77082
Simply replace:
.filter_by(year=year)
.filter_by(month=month)
with:
from sqlalchemy.sql.expression import func
# ...
.filter(func.year(Logs.timestamp) == year)
.filter(func.month(Logs.timestamp) == month)
Read more on this in SQL and Generic Functions section of documentation.
Upvotes: 2