2017-08-01 3 views
0

私は構築しているアプリケーションを持っており、特にMS SQLとPostgreSQLのいくつかのデータベースに移植できるようにしたいと考えています。私が直面している具体的な問題はdatetimeのデータ型で処理されています。SQL Alchemyの日時とデータベースの方言

たとえば、以下の履歴表とグループをuser_idで取得し、各ユーザーの合計時間を取得します。 time_inがNullの場合、現在の日時を取得する必要があります。

私の質問は、データベース固有のSQL Alchemyコードを記述する必要がありますか?datdiffのようなデータベース固有の関数を使用せずに、以下のクエリの同じ結果を達成する方法はありますか? SQL Serverのではなく、PostgreSQLのために働く

サンプルクエリ:

history_timecase = case([(History.time_in == None, func.now())], else_=History.time_in) 

user_list = db.session.query(History.user_id, func.sum(func.datediff(text('minute'), History.time_in, history_timecase)))\ 
      .group_by(History.user_id).all() 

履歴表:

+----+---------+----------------+-----------------+ 
| id | user_id | time_in  | time_out  | 
+----+---------+----------------+-----------------+ 
| 11 |  2 |    | 8/1/2017 8:14 | 
| 12 |  2 |    | 8/1/2017 8:14 | 
| 13 |  2 |    | 8/1/2017 8:14 | 
| 14 |  2 |    | 8/1/2017 8:14 | 
| 15 |  2 |    | 8/1/2017 8:14 | 
| 16 |  2 |    | 8/1/2017 8:14 | 
| 17 |  11 |    | 7/31/2017 11:30 | 
| 6 |  6 | 8/1/2017 9:25 | 8/1/2017 8:06 | 
| 18 |  12 |    | 8/1/2017 9:34 | 
| 9 |  9 | 8/1/2017 9:40 | 8/1/2017 8:51 | 
| 10 |  10 | 8/1/2017 10:00 | 8/1/2017 8:55 | 
| 22 |  14 | 8/1/2017 10:00 | 8/1/2017 9:51 | 
| 23 |  14 | 8/1/2017 10:00 | 8/1/2017 9:51 | 
| 24 |  14 | 8/1/2017 10:00 | 8/1/2017 9:51 | 
| 7 |  7 | 8/1/2017 10:15 | 8/1/2017 8:37 | 
| 25 |  14 | 8/1/2017 10:15 | 8/1/2017 10:04 | 
| 27 |  14 | 8/1/2017 10:15 | 8/1/2017 10:05 | 
| 28 |  14 | 8/1/2017 10:15 | 8/1/2017 10:05 | 
| 29 |  12 | 8/1/2017 10:15 | 8/1/2017 10:06 | 
| 26 |  15 | 8/1/2017 10:45 | 8/1/2017 10:05 | 
| 33 |  16 | 8/1/2017 11:15 | 8/1/2017 10:24 | 
| 37 |  18 |    | 8/1/2017 11:19 | 
| 34 |  17 | 8/1/2017 11:35 | 8/1/2017 10:38 | 
| 30 |  14 | 8/1/2017 11:40 | 8/1/2017 10:18 | 
| 31 |  14 | 8/1/2017 11:40 | 8/1/2017 10:18 | 
| 32 |  14 | 8/1/2017 11:40 | 8/1/2017 10:18 | 
+----+---------+----------------+-----------------+ 
+0

を。 – univerio

+0

私はdatediffがSQL Serverに固有であることを認識しています。私は、データベース固有の機能を使用せずに私が何を達成するための別の方法があるかどうかを知りたいと思います。 – ians

+0

できるだけ多くのDB固有のコードを[カスタムコンパイルされた構造体](http://docs.sqlalchemy.org/en/latest/core/compiler.html#further-examples)にカプセル化しようとすることができます。表面上では、いくつかの計算のためにDBに依存しない構文を提供します。これは、DB固有の実装にコンパイルされます。 –

答えて

0

DateDiff関数は、()SQL Serverのためにあまりにも具体的です。

彼はpostgresのでインターバル機能引くカスタムを使用することを特徴とする私が提案ソリューションのリンクを掲載しています:datediff`は、SQL Serverに固有である `ので、はい

https://groups.google.com/forum/#!topic/sqlalchemy/6mSpNTMjUGU

from sqlalchemy import func 
    from sqlalchemy.sql.expression import FunctionElement 
    from sqlalchemy.ext.compiler import compiles 

    class subtract_interval(FunctionElement): 
     type = Date() 
     name = 'subtract_interval' 

    @compiles(subtract_interval) 
    def compile_subtract_interval(element, compiler, **kwargs): 
     return '(%s::date - %s::interval)' % (
      compiler.process(element.clauses.clauses[0]), 
      compiler.process(element.clauses.clauses[1]), 
    ) 

    res = session.query(Foo).filter(
     Foo.date < subtract_interval(func.now(), '3 years') 
).all()