aim 查询中不一致的日期时间偏移量

ki0zmccv  于 2个月前  发布在  其他
关注(0)|答案(2)|浏览(24)

🐛 Bug

我运行了以下查询 in the browser :

datetime(2023,  6, 13, 10, 23, 18) <= run.created_at <= datetime(2023,  6, 13, 13, 35, 13)

当我运行我的代码(如下所示),唯一能保证给我相同结果的查询是,如果我将日期时间偏移7小时:

datetime(2023,  6, 13, 17, 23, 18) <= run.created_at <= datetime(2023,  6, 13, 20, 35, 13)

请注意,我居住在太平洋时区,目前为UTC-8。

重现问题

import aim

AIM_REPO_PATH = "/home/mulhaq/data/aim/pc-mordor/pcc"
QUERY = "datetime(2023,  6, 13, 17, 23, 18) <= run.created_at <= datetime(2023,  6, 13, 20, 35, 13)"

repo = aim.Repo(AIM_REPO_PATH)
runs = [x.run for x in repo.query_runs(QUERY).iter_runs()]
print("\n".join(f"{run.hash} {run.created_at}" for run in runs))

预期行为

重要提示:SDK查询应始终与浏览器提供相同的结果。
在这种情况下,每次查询都应使用RestrictedPython相同的日期时间区域设置/环境等。

环境

  • Aim版本:3.1
  • Python版本:3.11
  • pip版本:23.1.2
  • 操作系统:Arch Linux
  • 其他相关信息:无

附加上下文

9rnv2umw

9rnv2umw1#

Consider:
aim/aim/sdk/query_utils.py
Lines 46 to 48 in 6757c5e
| | ifitem=='created_at': |
| | returngetattr(self.db.caches['runs_cache'][self.hash], item)\ |
| | -datetime.timedelta(minutes=self._timezone_offset) |
When I ran the above code, self._timezone_offset == 0 , so no delta is applied.
Actually, consider:
aim/aim/sdk/query_utils.py
Lines 36 to 48 in 6757c5e
| | ifitemin ['finalized_at', 'end_time']: |
| | end_time=self.meta_run_tree['end_time'] |
| | ifitem=='finalized_at': |
| | ifnotend_time: |
| | returnNone |
| | else: |
| | returndatetime.datetime.fromtimestamp(end_time, tz=pytz.utc).replace(tzinfo=None)\ |
| | -datetime.timedelta(minutes=self._timezone_offset) |
| | else: |
| | returnend_time |
| | ifitem=='created_at': |
| | returngetattr(self.db.caches['runs_cache'][self.hash], item)\ |
| | -datetime.timedelta(minutes=self._timezone_offset) |
All the times ['created_at', 'finalized_at', 'end_time'] are all handled using different methods. In fact, only end_time is present in self.meta_run_tree :

>>> list(self.meta_run_tree.keys())
['attrs', 'contexts', 'end_time', 'traces']

>>> dir(self.db.caches['runs_cache'][self.hash])
['__abstractmethods__', '__class__', '__class_getitem__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__mapped_properties__', '__model__', '__module__', '__ne__', '__new__', '__orig_bases__', '__parameters__', '__reduce__', '__reduce_ex__', '__repr__', '__schema__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__', '_abc_impl', '_id', '_is_protocol', '_model', '_session', 'add_note', 'add_tag', 'all', 'archived', 'created_at', 'creation_time', 'delete_run', 'description', 'end_time', 'experiment', 'experiment_obj', 'fields', 'finalized_at', 'find', 'find_many', 'find_note', 'from_hash', 'from_model', 'hash', 'info', 'name', 'notes', 'notes_obj', 'remove_note', 'remove_tag', 'search', 'tags', 'tags_obj', 'update_note', 'updated_at']

>>> self.db.caches['runs_cache'][self.hash].created_at
datetime.datetime(2023, 6, 15, 18, 1, 1, 878988)
>>> self.db.caches['runs_cache'][self.hash].finalized_at
>>> self.db.caches['runs_cache'][self.hash].end_time

(Interestingly, finalized_at and end_time are None .)

h43kikqp

h43kikqp2#

要修复,我尝试了这个方法:

return getattr(self.db.caches["runs_cache"][self.hash], item).replace(
                tzinfo=pytz.utc
            ) - datetime.timedelta(minutes=self._timezone_offset)

...但这使得查询变得有点棘手,因为:
查询失败,无法比较无偏移量和有偏移量的日期时间
...一个潜在的不准确的修复方法是将它们转换为本地的无偏移量日期时间:

dt_utc = getattr(self.db.caches["runs_cache"][self.hash], item).replace(tzinfo=pytz.utc)
            return dt_utc.astimezone(tz=None).replace(tzinfo=None)
            # Not sure what to do about:
            # - datetime.timedelta(minutes=self._timezone_offset)

...这可以工作,但在某些情况下可能会出现问题,例如在夏令时更改时运行查询,或者你可能正在乘坐飞机穿越时区,或者如果你是一个时间旅行者并且回到过去 [随机时间偏移发生],或者跨越闰秒/年/ centuries ...另一方面,它似乎与浏览器查询做相同的事情,至少从表面上看是这样。
“技术上”最佳的折衷方案是在所有地方使用无偏移量的UTC日期时间,但这就是我创建这个bug报告的原因 - 浏览器界面和SDK接口实现了不同的行为。 :)
唉...时间真是太 unnecessarily complicated 了!

相关问题