实现标题几乎等同于如何在 sqlalchemy 过滤器中使用带标签的列?我认为这是一个单独的问题。
为了大大简化我的问题:假设我有两个查询,每个查询都返回我想要的结果的子集,我将它们联合在一起:
initial_task = "initial_task"
scheduled_task = "scheduled_task"
initial = session.query(Task.task_id,
User.signup_date.label('due_date'),
literal(initial_task).label('type'))\
.join(Task.user)
schedule = session.query(Task.task_id,
Schedule.due_date.label('due_date'),
literal(scheduled_task).label('type'))\
.join(Task.schedule)
tasks = initial.union_all(schedule)
Run Code Online (Sandbox Code Playgroud)
需要明确的是:我意识到这个例子可以在没有联合的情况下重写;我的实际用例有五个单独的查询,除了结果强制转换为这种正常格式之外,几乎没有任何共同点。
如何过滤tasks以仅包含 2017 年 4 月 1 日之后到期的任务?从概念上讲,类似于:
tasks.filter(tasks.c.due_date >= datetime(2017, 4, 1))
Run Code Online (Sandbox Code Playgroud)
主要问题是我不知道如何以due_date一般方式引用该专栏。我从文档中尝试的所有内容似乎都在谈论较低级别的 API,并且在 ORM 层上导致:
'Query' object has no attribute 'c'
Run Code Online (Sandbox Code Playgroud) 我有一个代表交付的 SQLAlchemy 模型;交货有目的地、包裹 ID 和日期:
class Delivery(Base):
delivery_id = Column(Integer, primary_key=True, autoincrement=True)
parcel_id = Column(ForeignKey('parcels.parcel_id'))
scheduled_date = Column(DateTime)
destination_id = Column(ForeignKey('location.location_id'))
Run Code Online (Sandbox Code Playgroud)
现在,同一包裹的投递始发地与先前投递的目的地相同。我没有通过维护基于指针的链接列表来非规范化该信息,而是使用计划日期来订购交货,目前如下所示:
def origin(delivery):
prior = session.query(Delivery)
.filter(
Delivery.parcel_id == delivery.parcel_id,
Delivery.scheduled_date < delivery.scheduled_date,
)
.order_by(Delivery.scheduled_date.desc())
.first()
return prior.location_id if prior else None
Run Code Online (Sandbox Code Playgroud)
在纯 SQL 中,我可以将这个单独的查询转换为一个简单的子查询 + 连接,我在加载交付时将其包含在内。我已经足够了,我可以加载当前交付之前发生的所有相关交付:
_prior_delivery = \
select([Delivery.parcel_id, Delivery.scheduled_date, Location]) \
.where(and_(Location.location_id == remote(Delivery.location_id)) \
.order_by(Delivery.scheduled_date.desc()) \
.alias("prior_delivery")
Delivery.origin = relationship(
Location,
primaryjoin=and_(_prior_delivery.c.parcel_id == foreign(Delivery.parcel_id),
_prior_delivery.c.scheduled_date < foreign(Delivery.scheduled_date)),
secondary=_prior_delivery,
secondaryjoin=_prior_delivery.c.location_id == foreign(Location.location_id),
uselist=False, …Run Code Online (Sandbox Code Playgroud) 我正在以大约10b到16000b的块写入文件,当突然每个块被切断大约4050字节(具体地,4050,4051和4074字节,按此顺序).这意味着后续写入将覆盖应该写入的数据,从而弄乱我的数据.4050b以下的任何块都写得很好.
不幸的是,我无法重现它.我所拥有的只是混乱的文件,所以我正在调试寻找导致这种情况的东西.
调试它,我意识到c的write()函数在引擎盖下被调用(这是Java代码,FileChannel.write(),但是标准库调用c的写入并且只检查写入的字节> 0),以及它的文档不保证它会写出所有要求的数据,只是它会告诉你写了多少.
我不检查在Java土地上写回的字节(但我确实得到它,函数签名几乎完全相同),所以修复很简单.但是,由于我无法重现这一点,我不知道我已经解决了实际问题.因此,我希望有些c guru可以告诉我,我冒烟,或者有合法的情况,write()一次不能写超过4050个字节.
这是在64位Linux内核版本3.0.0-26上运行.
编辑:根据以下评论展开:
我正在写一个普通的文件系统文件.我不确定在这种情况下非阻塞意味着什么,我没有使用回调或任何东西,但明确告诉操作系统不会为每个块执行刷新到磁盘.使用Java的RandomAccessFile,'rw'模式打开该文件.