日時フィールドを持つログというテーブルがあります。特定の日付形式に基づいて、日付と行数を選択したいと考えています。
SQLAlchemy を使用してこれを行うにはどうすればよいですか?
日時フィールドを持つログというテーブルがあります。特定の日付形式に基づいて、日付と行数を選択したいと考えています。
SQLAlchemy を使用してこれを行うにはどうすればよいですか?
一般的な SQLAlchemy の回答がわかりません。ほとんどのデータベースは、通常は関数を介して、何らかの形式の日付フォーマットをサポートしています。SQLAlchemy は、sqlalchemy.sql.func を介した関数の呼び出しをサポートしています。たとえば、Postgres バックエンドで SQLAlchemy を使用し、テーブル my_table(foo varchar(30), when timestamp) を使用すると、次のようなことができます
my_table = metadata.tables['my_table']
foo = my_table.c['foo']
the_date = func.date_trunc('month', my_table.c['when'])
stmt = select(foo, the_date).group_by(the_date)
engine.execute(stmt)
月に切り捨てられた日付でグループ化します。ただし、この例では、date_trunc() が Postgres の日時関数であることに注意してください。他のデータベースは異なります。基礎となるデータベースについては言及していません。それを行うデータベースに依存しない方法がある場合、私はそれを見つけたことがありません。私の場合、Postgres に対して本番環境とテストを実行し、SQLite に対して単体テストを実行し、単体テストで SQLite ユーザー定義関数を使用して Postgress 日時関数をエミュレートしました。
フォーマットされていない日時列でグループ化した場合でも、カウントしても同じ結果が得られますか?その場合は、クエリを実行し、後でPython dateのstrftime()メソッドを使用できます。すなわち
query = select([logs.c.datetime, func.count(logs.c.datetime)]).group_by(logs.c.datetime)
results = session.execute(query).fetchall()
results = [(t[0].strftime("..."), t[1]) for t in results]
私はSQLAlchemyを知らないので、的外れかもしれません。ただし、必要なのは次のことだけだと思います。
SELECT date_formatter(datetime_field, "format-specification") AS dt_field, COUNT(*)
FROM logs
GROUP BY date_formatter(datetime_field, "format-specification")
ORDER BY 1;
OK、ORDER BY は必要ないかもしれませんし、日付式を再指定したほうがよいかもしれません。次のような代替案が考えられます。
SELECT dt_field, COUNT(*)
FROM (SELECT date_formatter(datetime_field, "format-specification") AS dt_field
FROM logs) AS necessary
GROUP BY dt_field
ORDER BY dt_field;
などなど。基本的に、日時フィールドをフォーマットしてから、フォーマットされた値に対してグループ化などを行います。