2013-01-10 29 views
14

在我的Django項目中,我有一個第三方應用程序的依賴關係,該應用程序在具有已知模式的各種目錄中生成SQLite高速緩存文件。Django:動態數據庫文件

我想使用Django模型來訪問這些數據庫,但顯然我不能使用靜態的DATABASES設置。

如何在任意路徑上動態打開SQLite數據庫?

EDIT

作爲拜倫露絲指出的那樣,解決方案是結合在查詢集的using功能使用django.db.connections

+0

爲什麼不能使用DATABASES?從我看到Django作者爲什麼這麼做的原因!另一種選擇是使用原始的sql(http://docs.python.org/2/library/sqlite3.html),但有點擊敗框架的目的! – StefanNch

+0

@StefanNch:我無法使用'DATABASES'設置,因爲我無法知道最終會使用哪些數據庫,因爲它們是動態添加的*。是的,我目前使用的sqlite3 API,我不完全滿意,因爲我不想挖掘到SQL。 – Constantinius

+0

這是一個有趣的建築,但現在我看到你的問題... – StefanNch

回答

29

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'] 
+1

我認爲這是我尋找的解決方案。我會試一試! – Constantinius

+0

這就是它,我能夠動態選擇一個數據庫文件,打開它並使用我的模型。 (儘管如此,這需要查詢集上的「使用」功能)。 – Constantinius

+0

不錯!嗯...所以這個連接需要添加每個需要使用db的傳入請求?可能很高興將它包裝在一些中間件中,以便在請求進入時設置數據庫... – monkut

4

您可以在數據庫設置中註冊數據庫。

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 

你可以但你不應該。

+0

這看起來很有趣,我會試試看。但我更喜歡一個解決方案,我不需要改變'DATABASES'設置。 – Constantinius

+1

您不應在運行時更改應用程序中的設置。例如,不要在視圖中執行此操作:https://docs.djangoproject.com/en/dev/topics/settings/#altering-settings-at-runtime –

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 
    } 
} 
+0

我會繼續這樣做。如果DB位置在運行時動態更改,請確保get_db_loc()根據哪個數據庫當前處於活動狀態(將該信息存儲在文本文件/全局變量中)更改其行爲,然後將get_db_loc()實時重定向到當前活動的DB。 –

+1

我不確定這會起作用,因爲函數'get_db_loc'只計算一次,而不是每次讀取'DATABASES'。但除此之外,感謝捐款。 – Constantinius

+0

沒錯,這是行不通的。 'get_db_loc()'的結果只是一個字符串。沒有什麼特別的,它是通過調用一個函數來獲得的,並且沒有什麼說可以再次調用該函數。 – rspeer