【问题标题】:How to select the MIN() of an ORM attribute and a literal datetime?如何选择 ORM 属性的 MIN() 和文字日期时间?
【发布时间】:2011-10-27 07:31:27
【问题描述】:

如何在 SQL Alchemy v0.6.4 中获取日期时间列的 MIN() 和文字日期时间?我想将日期时间结果限制在特定范围内。

我一直在使用sqlalchemy.func.min(column, literal_datetime)。这在 SQLite 中似乎可以正常工作,但在 MySQL 中则完全不行,这无疑意味着我要解决这个问题。 MySQL的错误是:

sqlalchemy.exc.ProgrammingError: (ProgrammingError) (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' '2011-06-14 12:30:00') AS min_1 \nFROM example' at line 1") 'SELECT min(example.my_datetime, %s) AS min_1 \nFROM example' (datetime.datetime(2011, 6, 14, 12, 30),)
  • 如何以便携的方式限制日期时间结果?
  • (我真的必须在我的应用程序中这样做吗?)

这是我一直用来探索问题的方法 - 工作正常,如此处所示(使用基于内存的 SQLite DB),不适用于 MySQL:

#!/usr/bin/env python

import random
from datetime import datetime

import sqlalchemy as sa
import sqlalchemy.orm as orm
from sqlalchemy.ext.declarative import declarative_base

orm_base = declarative_base()

class MyClass( orm_base ):
    __tablename__ = "example"
    pri_key  = sa.Column(sa.Integer(), primary_key=True)
    my_datetime  = sa.Column(sa.DateTime(), index=True)

engine = sa.create_engine("sqlite:///:memory:", echo=True)

Session = orm.sessionmaker( bind=engine )

orm_base.metadata.bind = engine
orm_base.metadata.create_all()

# Create test-data

session = Session()

random.seed(1234567980)
for i in range(100):
    month = random.randint(1, 12)
    day = random.randint(1, 28)
    hour = random.randint(0, 23)
    minute = random.randint(0, 59)

    my_instance = MyClass()
    my_instance.my_datetime = datetime(2011, month, day, hour, minute)

    session.add( my_instance )

session.commit()
session.close()

# Problem starts here

session = Session()
literal_datetime = datetime(2011, 06, 14, 12, 30)
print session.query( sa.func.min(MyClass.my_datetime) ).one()  # OK
print session.query( sa.func.min(MyClass.my_datetime, literal_datetime) ).all()  # Error in MySQL

我不是 SQL 专家,但数据库可移植性对我来说很重要,因此欢迎任何关于如何在未来避免此类陷阱的提示。

【问题讨论】:

    标签: mysql sqlite datetime sqlalchemy portability


    【解决方案1】:

    使用sqlalchemy.sql.expression.case 表达式,mySqlSQLite 均支持该表达式。

    SQLitemin/max 函数支持对多个值的非聚合操作。 mySql 不支持此功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多