免責事項1の日時セクションに基づいて:実際にはどこにでもpostgresql
代わりのsqliteのを使用して「安い」でない場合すべてのまず、と思います。私は開発/生産上の違いがあると思いますが、これは避けるべきです。最新のOSにpostgresql
をインストールすることは非常に簡単です。
上記はオプションではないと思っていますが、これからも続けましょう。
免責事項2:カスタムSQL構成(@ Joshの回答に従って)を使用したソリューションは、これを実現する実際の唯一の方法です。 残念なことに、提案された解決策は実際にはsqlite
では機能せず、ほんの数行で解決できなかったため、別個の回答となりました。
ソリューション: 次のモデルを持っていると仮定すると:
class Appointment(Base):
__tablename__ = 'appointment'
id = Column(Integer, primary_key=True)
name = Column(String(255))
datetime = Column(DateTime) # @note: should be better named `start_date`?
duration = Column(Integer)
sqlite
は特に追加/日付から間隔を減じ、日付操作を扱う本当に難しいです。したがって、のは多少異なるそれに近づくと数分で2つの日付の間の間隔を取得するカスタム関数を作成してみましょう:、
class diff_minutes(expression.FunctionElement):
type = Integer()
name = 'diff_minutes'
@compiles(diff_minutes, 'sqlite')
def sqlite_diff_minutes(element, compiler, **kw):
dt1, dt2 = list(element.clauses)
return compiler.process(
(func.strftime('%s', dt1) - func.strftime('%s', dt2))/60
)
@compiles(diff_minutes, 'postgresql')
def postgres_diff_minutes(element, compiler, **kw):
dt1, dt2 = list(element.clauses)
return compiler.process(func.extract('epoch', dt1 - dt2)/60)
あなたは既に次のクエリを使用して、チェックを実装することができます(私は私の例でlimit(1).one_or_none
を追加していないですがこれを使用しますあなたのデータは、任意の時間に対して)
q = (
session
.query(Appointment)
.filter(Appointment.datetime <= func.now())
.filter(diff_minutes(func.now(), Appointment.datetime) <= Appointment.duration)
)
しかし、今は、現在の時刻(func.now()
)によって限定されるものではなく、あなたはチェック(およびユニットテストできます:
あなたはそれを必要とするとき、明らかに)を行うことができます
# at_time = func.now()
at_time = datetime.datetime(2017, 11, 11, 17, 50, 0)
q = (
session
.query(Appointment)
.filter(Appointment.datetime <= at_time)
.filter(diff_minutes(at_time, Appointment.datetime) <= Appointment.duration)
)
ここでは、問題はで解決され、使用する両方のデータベースエンジンで解決するはずです。
BONUS:
あなたはにイベントがHybrid Methodsを使用して、現在あるかどうかをチェックするのインプリメンテーションを非表示にすることができます。
Appointment
クラスに以下を追加できます:
@hybrid_method
def is_current(self, at_time=None):
if at_time is None:
at_time = datetime.datetime.now()
return self.datetime <= at_time <= self.datetime + datetime.timedelta(minutes=self.duration)
@is_current.expression
def is_current(cls, at_time=None):
if at_time is None:
at_time = datetime.datetime.now()
stime = cls.datetime
diffm = diff_minutes(at_time, cls.datetime)
return and_(diffm >= 0, cls.duration >= diffm).label('is_current')
最初のものは、あなたが(のpythonではなく、SQL側の)メモリのチェックを実行することができます:
print(my_appointment.is_current())
秒1を
q = session.query(Appointment).filter(Appointment.is_current(at_time))
ここで、の場合、次のようなクエリを作成できます。 0を指定しないと、現在の時刻が使用されます。あなたの例では
current_appointment = session.query(Appointment).filter(Appointment.is_current()).limit(1).one_or_none()
を、あなたのロジックが反転していません。あなたが望むようにあなたは、もちろん、クエリを修正することができますか?次のように、* [now、now + duration] *の間の 'Appointment.datetime'があります。また、 'TIMESTAMPADD'はPostgreSQLの関数でさえありますか? –