【发布时间】:2014-04-21 05:43:34
【问题描述】:
我是 SQLAlchemy 的新手(但不是那么新)。我正在为一个项目使用 0.9.3 版本。我想查询 SQLite 数据库过滤结果以获取那些没有时间戳或自上次更新以来超过 24 小时的对象(在同一列上)。
问题是,我不知道如何实现时间过滤部分,我做了一个 IPython Notebook 会话,所以人们可以看看尝试了多长时间来寻找我的问题的答案:
在 [1] 中:
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Unicode, DateTime, Integer, create_engine
from sqlalchemy.orm import sessionmaker, relationship, backref
from datetime import datetime
engine = create_engine('sqlite:///:memory:')
Base = declarative_base()
Session = sessionmaker(bind=engine)
session = Session()
在 [2] 中:
class Product(Base):
__tablename__ = "product"
id = Column(Integer, primary_key=True)
name = Column(Unicode(140), unique=True, nullable=False)
department = Column(Unicode(20))
added = Column(DateTime, default=datetime.now)
last_time_parsed = Column(DateTime)
def repr(self):
return "<Product(name=%s, department=%s, added=%s, last_time_parsed=%s)>" % (
self.name, self.department, self.added, self.last_time_parsed)
在 [3] 中:
# create the tables
Base.metadata.create_all(engine)
在 [4] 中:
# create a false product
p1 = Product(name="Product X")
p2 = Product(name = "Product Y")
p3 = Product(name = "Product Z")
在 [5] 中:
session.add(p1)
session.add(p2)
session.add(p3)
session.commit()
/home/jorge/projects/project1/lib/python2.7/site-packages/sqlalchemy/engine/default.py:525: SAWarning: Unicode type received non-unicode bind param value.
param.append(processors[key](compiled_params[key]))
在 [7] 中:
q = session.query(Product).filter(Product.last_time_parsed == None).filter(Product.last_time_parsed > 24)
在 [9] 中:
print q.first().name
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-9-377361de0bab> in <module>()
----> 1 print q.first().name
AttributeError: 'NoneType' object has no attribute 'name'
在 [14] 中:
q = session.query(Product).filter(Product.last_time_parsed == None)
在 [15] 中:
print q.first().name
Product X
在 [16] 中:
q = session.query(Product).filter(Product.last_time_parsed < 24)
print q.first().name
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-16-b10ccbb5d88d> in <module>()
1 q = session.query(Product).filter(Product.last_time_parsed < 24)
----> 2 print q.first().name
AttributeError: 'NoneType' object has no attribute 'name'
在 [20] 中:
q = session.query(Product).filter(Product.added > 24)
print q.first().name
Product X
在 []:
在input 20 中,我知道Product.added 是DateTime 数据类型(我只是用来测试,因为它是唯一保存DateTime 值的列)。我不明白的是逻辑陈述。如果是Product.added < 24(如input 16 所示)而不是Product.added > 24,我将不会从数据库中获得任何对象。那么,通过数字24 对数据库的理解究竟是什么? 24 分钟? 24小时? 24 秒? 24 天?
那么,我该如何过滤数据以获取没有时间戳或更新时间超过 24 小时的数据?
谢谢:)
【问题讨论】:
-
而不是值
24,你能不能与当前时间前24小时的datetime值进行比较?例如datetime.now() - timedelta(hours=24) -
我刚刚发现了这一点。但我做了类似
onedayold = datetime.timedelta(hours=24)的操作,然后在查询中使用它来过滤所有不超过 24 小时的数据。喜欢:q = session.query(Product).filter(Product.added < onedayold); qn = q.all(); print qn产生[],因为添加的数据不超过 24,所以结果正确。但是,我仍然错过了包含last_time_parsed列的每个产品的步骤None具有价值。 -
您无法将
added与timedelta对象进行比较。 2014-03-15 08:12:33 少于 24 小时是什么意思?您必须将其与 2014-03-14 15:52:40 进行比较。由于 2014-03-15 08:12:33 发生在 2014-03-14 15:52:40 之后,因此它更大。因此,要查找datetime是否在过去 24 小时内出现,您必须执行Product.added > datetime.now() - timedelta(hours=24)。
标签: python time orm sqlalchemy python-datetime