在 Django 中将固定装置加载到数据库后如何延迟评估 ORM 调用?

发布于 2024-09-07 05:19:11 字数 1014 浏览 1 评论 0原文

我有一个模块 pagetypes.py 从数据库中提取几个常量(我不应该在这里真正使用单词常量)以供以后重用:

def _get_page_type_(type):
    return PageType.objects.get(type=type)

PAGE_TYPE_MAIN = _get_page_type_('Main')
PAGE_TYPE_OTHER = _get_page_type_('Other')

然后在视图中的某个地方我所做的:

import pagetypes
...
print pagetypes.PAGE_TYPE_MAIN #simplified

一切正常当数据库有这些记录并且我确保它有时就很好......除非此代码正在测试中。在这种情况下,我想通过固定装置将这些记录加载到数据库中。问题是,在导入 pagetypes 模块时,固定装置尚未加载(甚至 syncdb 未运行),导致 _get_page_type_ 调用失败,并显示:

psycopg2.ProgrammingError: relation "pagetype" does not exist

测试运行程序始终尝试导入 pagetypes 模块,因为它是由正在测试的视图导入的。

我该如何解决这个问题?

我正在考虑延迟加载页面类型常量PAGE_TYPE_MAINPAGE_TYPE_OTHER,但是如果这些记录不在数据库中(或者在测试时的固定装置中),我希望它尽早失败,所以我真的不知道如何实现这个。

我也在考虑对象级缓存,只要使用/调用常量就调用 PageType.objects.get(type=type) ,但这不是一种矫枉过正吗?在没有缓存的情况下调用 orm 会导致过多的数据库调用,这是我想防止的。

这一定是非常简单的事情,但我无法解决。 ;-)

I've got a module pagetypes.py that extracts a couple of constants (I shouldn't really use word constant here) from the db for later reuse:

def _get_page_type_(type):
    return PageType.objects.get(type=type)

PAGE_TYPE_MAIN = _get_page_type_('Main')
PAGE_TYPE_OTHER = _get_page_type_('Other')

then somewhere in views I do:

import pagetypes
...
print pagetypes.PAGE_TYPE_MAIN #simplified

It all works fine when db has those records and I make sure it does... unless this code is under test. In that case I want to load those records into db via fixtures. The problem with that is that fixtures are not loaded (even syncdb is not run) by the time pagetypes module is imported resulting in _get_page_type_ call failing with:

psycopg2.ProgrammingError: relation "pagetype" does not exist

Test runner always tries to import pagetypes module, because it is imported by view that is under test.

How do I get around this problem?

I was thinking of lazily loading pagetype constants PAGE_TYPE_MAIN, PAGE_TYPE_OTHER, but then I want it to fail early if those records are not in the db (or fixtures if under test), so I don't really know how to implement this.

I was also thinking of object level caching and just call PageType.objects.get(type=type) whenever constant is used/called, but wouldn't that be an overkill? Calling orm without cache would result in too many db calls, which I want to prevent.

It must be something very simple, but I can't work it out. ;-)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

最初的梦 2024-09-14 05:19:11

我将使用函数而不是常量,但会记住它们:

_cache = {}

def get_page_type(type_name):
    if type_name not in _cache:
        _cache[type_name] = PageType.objects.get(type=type_name)
    return _cache[type_name]

所以现在您可以在必要时直接调用 get_page_type('Main')

I would use the functions instead of the constants, but memoize them:

_cache = {}

def get_page_type(type_name):
    if type_name not in _cache:
        _cache[type_name] = PageType.objects.get(type=type_name)
    return _cache[type_name]

So now you'd call get_page_type('Main') directly when necessary.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文