按tim筛选sqlalchemy sqlite datetime列

2024-05-12 14:22:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我不确定如何仅使用时间字段过滤数据库。现在我有一个名为DatabasePolgygon的类

class DatabasePolygon(dbBase):
    __tablename__ = 'objects'

    begin_time = Column(DateTime) # starting time range of shape
    end_time = Column(DateTime) # ending time range of shape
    # Other entries not relevant to this question

开始时间和结束时间可以等于2006-06-01 14:45:23,它们表示对象(在本例中是图形在绘图上)覆盖的X轴范围。我想允许对我的用户进行高级搜索,特别是要求在一定时间范围内出现的所有对象。但是,如何使用DateTime字段来实现这一点呢?在

^{pr2}$

问题是我将一个带有Y-m-d H-M-S的datetime对象与一个只有H-M-S的对象进行比较。一个示例场景是,如果一个用户想要所有对象,而不管年/月/日,它们出现在14:45:24的范围之外,那么我们将使用rng['btime']=14:45:24和{},这两个对象在比较时似乎并没有实际过滤任何内容。在

有没有什么方法可以有效地比较这一列数据中的时间?我希望能做些类似的事情

        # Grab all shapes that appear above this certain time
        query_result = query_result.filter(
            DatabasePolygon.begin_time.time() >= datetime.strptime(rng['btime']), %H:%M:%S').time()
        )

Tags: of对象用户datetimetime时间rangecolumn
1条回答
网友
1楼 · 发布于 2024-05-12 14:22:55

这似乎是可能的,但有一些条件。在


目标1:完全做到。

使用名为Thing的类来保存“objects”表中的id和{}值:

class Thing(Base):
    __tablename__ = 'objects'

    id = Column(Integer, primary_key=True)
    begin_time = Column(DateTime)

    def __repr__(self):
       return "<Thing(id=%d, begin_time='%s')>" % (self.id, self.begin_time)

以及SQLite数据库的“objects”表中的测试数据

^{pr2}$

不幸的是,这不起作用:

engine = create_engine(r'sqlite:///C:\__tmp\test.db', echo=True)

Session = sessionmaker(bind=engine)
session = Session()
for instance in session.query(Thing)\
        .filter(Thing.begin_time[11:]<'17:00:00')\
        .order_by(Thing.id):
    print(instance)

生产

NotImplementedError: Operator 'getitem' is not supported on this expression

但是,这确实有效。。。在

engine = create_engine(r'sqlite:///C:\__tmp\test.db', echo=True)

conn = engine.connect()
result = conn.execute("SELECT id FROM objects WHERE substr(begin_time,12)<'17:00:00'")
id_list = [row[0] for row in result.fetchall()]
result.close()
conn.close()

Session = sessionmaker(bind=engine)
session = Session()
for instance in session.query(Thing)\
        .filter(Thing.id.in_(id_list))\
        .order_by(Thing.id):
    print(instance)


目标2:有效地进行

控制台输出显示第一个SELECT确实是

SELECT id FROM objects WHERE substr(begin_time,12)<'17:00:00'

所以如果我们使用SQLite 3.9.0或更高版本并创建了“表达式索引”

CREATE INDEX time_idx ON objects(substr(begin_time,12));

这样SQLite就可以避免表扫描。不幸的是,即使是目前最新版本的cpython2.7(2.7.11)仍然附带了一个太旧的sqlite3模块

Python 2.7.11 (v2.7.11:6d1b6a68f775, Dec  5 2015, 20:32:19) [MSC v.1500 32 bit (Intel)] on win32
>>> import sqlite3
>>> sqlite3.sqlite_version
'3.6.21'

因此,索引不能存在于数据库中,否则SQLAlchemy将阻塞它:

sqlalchemy.exc.DatabaseError: (sqlite3.DatabaseError) malformed database schema (time_idx) - near "(": syntax error [SQL: "SELECT id FROM objects WHERE substr(begin_time,12)<'17:00:00'"]

因此,如果“高效”部分非常重要,那么您可能需要说服Python使用更新版本的SQLite。在这个问题中可以找到一些指导

Force Python to forego native sqlite3 and use the (installed) latest sqlite3 version

相关问题 更多 >