【问题标题】:Django: dynamic database fileDjango:动态数据库文件
【发布时间】:2012-12-24 15:03:34
【问题描述】:

在我的 Django 项目中,我依赖于第三方应用程序,该应用程序在具有已知架构的各种目录中生成 SQLite 缓存文件。

我想使用 Django 模型来访问这些数据库,但显然我不能使用静态 DATABASES 设置。

如何在任意路径上动态打开 SQLite 数据库?

编辑

正如 Byron Ruth 指出的那样,解决方案是在 QuerySet 中将 django.db.connectionsusing 函数结合使用。

【问题讨论】:

  • 为什么不能使用数据库?从我所见,这就是 Django 的作者成功的原因!另一种选择是使用原始 sql (docs.python.org/2/library/sqlite3.html),但有点违背了框架的目的!
  • @StefanNch:我无法使用DATABASES 设置,因为我不知道最终会使用什么数据库,因为它们是动态添加的。是的,我目前正在使用 sqlite3 API,但我并不完全满意,因为我不想深入研究 SQL。
  • 这是一个有趣的架构,但现在我看到了你的问题......

标签: django django-models django-database


【解决方案1】:

您可以在 DATABASES 设置中注册数据库。

from your_project import settings
database_id = "unqique_name"
new_database = {}
new_database["id"] = database_id
new_database['ENGINE'] = 'django.db.backends.sqlite3'
new_database['NAME'] = '/project/data/db_%s.sql' % database_id
new_database['USER'] = ''
new_database['PASSWORD'] = ''
new_database['HOST'] = ''
new_database['PORT'] = ''
settings.DATABASES[database_id] = new_database

你可以,但你不应该。

【讨论】:

  • 这看起来很有趣,我会试一试。但我更喜欢不需要更改 DATABASES 设置的解决方案。
  • 您不应在运行时更改应用程序中的设置。例如,不要在视图中这样做:docs.djangoproject.com/en/dev/topics/settings/…
【解决方案2】:

假设使用的唯一引擎是 SQLite,并且(唯一)数据库文件的位置有所不同,请提供对 NAME 的可调用:

def get_db_loc():
    # code to determine filesystem location of database
    return location

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': get_db_loc(),
        # More config goes here
    }
}

【讨论】:

  • 我会支持这个。如果 DB 位置在运行时动态变化,请确保 get_db_loc() 根据当前活动的 DB 更改其行为(将该信息存储在文本文件/全局变量中),然后在 get_db_loc() 中实时重定向到当前活跃的数据库。
  • 我不确定这是否可行,因为函数 get_db_loc 只评估一次,而不是每次读取 DATABASES 时。但除此之外,感谢您的贡献。
  • 对,这不可能。 get_db_loc() 的结果只是一个字符串。它是通过调用函数获得的这一事实并没有什么特别之处,也没有什么可以说要再次调用该函数。
  • 啊,很公平。从函数调用更改为回调可能有效吗? get_db_loc() 变成 get_db_loc 耸耸肩
【解决方案3】:

django.db.connections 是在您的设置中定义的 DATABASES 的简单包装器。包装类在这里: django.db.utils#L137-L227

from django.db import connections

# Add connection information dynamically..
connections.databases['new-alias'] = { ... }
# Ensure the remaining default connection information is defined.
# EDIT: this is actually performed for you in the wrapper class __getitem__
# method.. although it may be good to do it when being initially setup to
# prevent runtime errors later.
# connections.databases.ensure_defaults('new-alias')

# Use the new connection
conn = connections['new-alias']

【讨论】:

  • 我认为这是我正在寻找的解决方案。我试试看!
  • 就是这样,我能够动态选择一个数据库文件,打开它并使用我的模型。 (不过,这需要查询集上的 using 函数)。
  • 不错!嗯...所以需要为每个需要使用数据库的传入请求添加此连接?将其包装在一些中间件中以在请求进入时设置数据库可能会很好......
  • @monkut 它们将在整个过程中被存储。快速if 'new-alias' not in connections.databases 检查将确保设置始终存在。附带说明一下,如果您真的想要一个临时数据库连接,试试这个:gist.github.com/bruth/7467130
  • 这个方法似乎也不允许`model_instance.save(using='new-alias')。有没有办法添加这个功能?
猜你喜欢
  • 2011-09-28
  • 2014-07-16
  • 1970-01-01
  • 2020-07-03
  • 2012-04-12
  • 2021-08-05
  • 2014-04-03
  • 2021-11-15
  • 1970-01-01
相关资源
最近更新 更多