2011-07-05 18 views
25

मैं django का मूल्यांकन कर रहा हूं और सोच रहा हूं कि निम्नलिखित संभव है या नहीं। मैंने पहले से ही नियमित रूप से एकाधिक डेटाबेस दस्तावेज़ों को देखा है, इसलिए कृपया मुझे उस पर इंगित न करें क्योंकि इस उपयोग के मामले का उल्लेख तब तक नहीं किया गया है जब तक मैं बाहर कर सकता हूं। अगर मैं गलत हूं तो मैं इसे वापस लेता हूं :)Django एकाधिक और गतिशील डेटाबेस

मुझे एक मुख्य डेटाबेस चाहिए जिसमें मेरे अधिकांश ऐप के मॉडल रहेंगे, हालांकि ऐप की एक इच्छा को गतिशील रूप से डेटाबेस बनाने की आवश्यकता होगी, ये ग्राहक विशिष्ट डेटाबेस होंगे।

डेटाबेस पथ (मैं स्क्लाइट का उपयोग करने की योजना बना रहा हूं) प्राथमिक डेटाबेस में संग्रहीत किया जाएगा और इसलिए कर्सर को बदलने की आवश्यकता होगी लेकिन मॉडल वही रहेगा।

मैं इसे प्राप्त करने के तरीकों पर किसी भी विचार का स्वागत करता हूं?

+0

आपको एकाधिक डेटाबेस का उपयोग क्यों करना है? क्या कोई कारण है कि आप अपने ऐप मॉडल (एस) स्कीमा को प्रत्येक ग्राहक के लिए जानकारी रखने के लिए समायोजित नहीं कर सकते हैं? प्रत्येक ग्राहक के लिए कई डेटाबेस होने के कारण अत्यधिक अनियमित होता है। –

+0

मैं इस समय उपयुक्त वास्तुकला निर्धारित करने की कोशिश कर रहा हूं। मुझे एकाधिक डेटाबेस का उपयोग नहीं करना है, लेकिन यह पोर्टेबल, ऑनलाइन और ऑफ़लाइन सेवाओं के प्रावधान प्रदान करने का एक विकल्प है। और इस अंत में मैं यह जानना चाहता हूं कि यह संभव है, यह काफी सरलता से सरल है लेकिन मुझे लगता है कि एक सामान्य ढांचे में इसका समर्थन करने में अभ्यास करना मुश्किल हो सकता है, इसलिए मैंने सोचा कि मैं देख सकता हूं कि किसी ने पहले ऐसा कुछ किया है या नहीं। – nickjb

+1

[डुप्गो: गतिशील डेटाबेस फ़ाइल] के संभावित डुप्लिकेट (http://stackoverflow.com/questions/14254315/django- गतिशील- डाटाबेस- फ़ाइल) (नोट: लिंक किया गया प्रश्न उचित समाधान प्रदान करता है, जिसके लिए इसकी आवश्यकता नहीं होती है जब भी कोई नया डेटाबेस जोड़ा/बदला/हटाया जाता है तो सर्वर को पुनरारंभ करने का कामकाज) – mgibsonbr

उत्तर

24

मैं "You should not edit settings at runtime" के साथ खुल जाऊंगा।

ऐसा कहकर, मेरे पास एक ही समस्या है, जहां मैं प्रत्येक उपयोगकर्ता के लिए एक अद्वितीय डेटाबेस बनाना चाहता हूं। ऐसा करने का कारण यह है कि मैं उपयोगकर्ता को अपने सर्वर पर संग्रहीत डेटाबेस से/सेव/एक्सेस करने की क्षमता प्रदान कर रहा हूं, जिसमें एकाधिक डेटाबेस हैं, और इस प्रकार प्रत्येक उपयोगकर्ता के लिए एक है।

यह उत्तर वांछित लक्ष्य प्राप्त करने के लिए अनुशंसित तरीका नहीं है। मुझे एक समस्या से संपर्क करने के लिए एक django-guru से सुनना अच्छा लगेगा। हालांकि, यह एक समाधान है जिसका मैं उपयोग कर रहा हूं और अब तक यह अच्छी तरह से काम कर रहा है। मैं स्क्लाइट का उपयोग कर रहा हूं हालांकि इसे किसी भी डेटाबेस के लिए आसानी से संशोधित किया जा सकता है।

  1. (कार्यावधि में) सेटिंग के लिए नए डेटाबेस जोड़े
  2. एक फ़ाइल बनाएँ (कार्यावधि में) जब सर्वर पुनरारंभ पुन: लोड के लिए इन सेटिंग्स को स्टोर करने के
  3. :

    सारांश में, इस प्रक्रिया है

  4. भागो एक स्क्रिप्ट जो सहेजी गई सेटिंग फ़ाइलों को लोड करता है (जब भी सर्वर पुनरारंभ)

अब, कैसे इस लक्ष्य को हासिल करने के लिए:

1) सबसे पहले, जब कोई नया उपयोगकर्ता बनाया जाता है, तो मैं सेटिंग्स में एक नया डेटाबेस बना देता हूं। यह कोड मेरे विचार में रहता है जहां नए उपयोगकर्ता बनाए जाते हैं।

from YOUR_PROJECT_NAME import settings 
database_id = user.username #just something unique 
newDatabase = {} 
newDatabase["id"] = database_id 
newDatabase['ENGINE'] = 'django.db.backends.sqlite3' 
newDatabase['NAME'] = '/path/to/db_%s.sql' % database_id 
newDatabase['USER'] = '' 
newDatabase['PASSWORD'] = '' 
newDatabase['HOST'] = '' 
newDatabase['PORT'] = '' 
settings.DATABASES[database_id] = newDatabase 
save_db_settings_to_file(newDatabase) #this is for step 2) 

यह स्क्रिप्ट django प्रोजेक्ट सेटिंग्स में डेटाबेस सेटिंग्स 'रनटाइम' को लोड करती है। हालांकि अगर सर्वर पुनरारंभ होता है, तो यह डेटाबेस अब सेटिंग्स में नहीं होगा।

2) जब भी सर्वर पुनरारंभ होता है, तो इन सेटिंग्स को स्वचालित रूप से पुनः लोड करने में सुविधा के लिए, मैं प्रत्येक डेटाबेस के लिए एक फ़ाइल बनाता हूं जो सर्वर प्रारंभ होने पर लोड हो जाएगा। इस फ़ाइल बनाना समारोह save_db_settings_to_file द्वारा किया जाता है:

def save_db_settings_to_file(db_settings): 
    path_to_store_settings = "/path/to/your/project/YOUR_PROJECT_NAME/database_settings/" 
    newDbString = """ 
DATABASES['%(id)s'] = { 
    'ENGINE': '%(ENGINE)s', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'. 
    'NAME': '%(NAME)s',      # Or path to database file if using sqlite3. 
    'USER': '',      # Not used with sqlite3. 
    'PASSWORD': '',     # Not used with sqlite3. 
    'HOST': '',      # Set to empty string for localhost. Not used with sqlite3. 
    'PORT': '',      # Set to empty string for default. Not used with sqlite3. 
} 
    """ % db_settings 
    file_to_store_settings = os.path.join(path_to_store_settings, db_settings['id'] + ".py") 
    write_file(file_to_store_settings, newDbString) #psuedocode for compactness 

3) वास्तव में इन सेटिंग्स को जब सर्वर शुरू कर दिया है, मैं /path/to/your/project/YOUR_PROJECT_NAME/settings.py के सबसे निचले भाग है, जो सेटिंग्स फ़ोल्डर में प्रत्येक फ़ाइल को लोड करता है के लिए एक एकल पंक्ति जोड़ें लोड करने के लिए और सेटिंग में डेटाबेस विवरण लोड करने के प्रभाव होने के साथ इसे चलाता है।

from settings import DATABASES 
import os 

path_to_store_settings = "/path/to/your/project/YOUR_PROJECT_NAME/database_settings/" 
for fname in os.listdir(path_to_settings): 
    full_path = os.path.join(path_to_settings, fname) 
    f = open(full_path) 
    content = f.read() 
    f.close() 
    exec(content) #you'd better be sure that the file doesn't contain anything malicious 

ध्यान दें कि आप इस कोड को सीधे settings.py के तल पर बजाय आयात बयान की डाल सकता है:

import settings_manager 

फिर, import settings_manager/path/to/your/project/YOUR_PROJECT_NAME/settings_manager.py पर फ़ाइल है, जो निम्नलिखित कोड शामिल लोड होगा , लेकिन आयात कथन का उपयोग settings.py के निरंतर स्तर को रखता है।

यह प्रत्येक डेटाबेस सेटिंग को लोड करने का एक सुविधाजनक तरीका है क्योंकि सेटिंग्स से डेटाबेस को निकालने के लिए आपको बस सेटिंग्स को हटा देना है, और अगली बार जब सर्वर पुनरारंभ होता है तो यह उन विवरणों को सेटिंग्स में लोड नहीं करेगा , और डेटाबेस सुलभ नहीं होगा।

जैसा कि मैंने कहा, यह काम करता है और मुझे अब तक इसका उपयोग सफलता मिली है, लेकिन यह आदर्श समाधान नहीं है। अगर कोई बेहतर समाधान पोस्ट कर सकता है तो मैं वास्तव में सराहना करता हूं।

क्या इसके बारे में बुरा है:

  • यह स्पष्ट सलाह Django टीम से कार्यावधि में सेटिंग नहीं संशोधित करने के लिए खारिज कर देता है। मुझे यह सलाह क्यों नहीं है कि यह सलाह क्यों दी गई है।
  • यह डेटा में सेटिंग्स को लोड करने के लिए exec कथन का उपयोग करता है। यह ठीक होना चाहिए, लेकिन अगर आपको उन फ़ाइलों में से किसी एक में भ्रष्ट या दुर्भावनापूर्ण कोड मिलता है तो आप एक दुखद पांडा होंगे।

ध्यान दें कि मैं अभी भी ऑथ और सत्र डेटा के लिए डिफ़ॉल्ट डेटाबेस का उपयोग करता हूं, लेकिन मेरे अपने ऐप्स से मौजूद सभी डेटा उपयोगकर्ता-विशिष्ट डेटाबेस में संग्रहीत है।

+0

मैं एक अलग समाधान के साथ आया हूं, हालांकि मैंने अपनी फाइल (फ़ाइलों के माध्यम से) और मेरा उपयोग किया है, डेटाबेस का उपयोग इन फ़ाइलों के लिए स्टोर के रूप में ही किया है । Settings.py की अंतिम पंक्ति उन सभी मॉडलों को लोड करती है जिनमें डेटाबेस परिभाषाएं होती हैं और उन्हें django की डेटाबेस सेटिंग में जोड़ती है। –

+2

यदि आप अपने मुख्य डेटाबेस में डीबी कनेक्शन लिखते हैं (जिसे आप उपयोगकर्ताओं को प्रबंधित करते हैं) तो आप इसे टेक्स्ट फ़ाइल से अधिक सुरुचिपूर्ण बना सकते हैं। – JulienD

7

@dawnrider के उत्तर को बढ़ाने के लिए, कुछ मामलों में settings.DATABASES संपादन पर्याप्त नहीं हो सकता है। यह django.db.connections.databases संपादित करने के लिए और अधिक विश्वसनीय हो सकता है, जो settings.DATABASES के आसपास एक कैश और रैपर के रूप में कार्य करता है।

उदा।

from django.db import connections 
database_id = user.username #just something unique 
newDatabase = {} 
newDatabase["id"] = database_id 
newDatabase['ENGINE'] = 'django.db.backends.sqlite3' 
newDatabase['NAME'] = '/path/to/db_%s.sql' % database_id 
newDatabase['USER'] = '' 
newDatabase['PASSWORD'] = '' 
newDatabase['HOST'] = '' 
newDatabase['PORT'] = '' 
connections.databases[database_id] = newDatabase 
संबंधित मुद्दे