2009-11-26 14 views
8

का उपयोग कर स्थापित अनुप्रयोगों में डेटाबेस संस्करणिंग मैं कई डेल्फी अनुप्रयोगों पर काम कर रहा हूं जिन्हें नए संस्करण जारी किए जाने पर और जब उपयोगकर्ता अतिरिक्त मॉड्यूल स्थापित करना चुनते हैं तो क्षेत्र में अपने डेटाबेस संरचनाओं को अपग्रेड करना होगा। एप्लिकेशन विभिन्न प्रकार के एम्बेडेड डेटाबेस (डीबीआईएसएएम और जेट वर्तमान में उपयोग कर रहे हैं, लेकिन यह बदल सकता है) का उपयोग कर रहे हैं।डेल्फी

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

मैं इसे कार्यान्वित करने के दो तरीकों को देख सकता हूं: डेटाबेस के साथ संस्करण संख्या संग्रहित करना और पुराने संस्करणों से नए संस्करणों तक पहुंचने के लिए डीडीएल स्क्रिप्ट का उपयोग करना या एप्लिकेशन के अंदर डेटाबेस संरचना का एक संदर्भ संस्करण संग्रहीत करना, संदर्भ के साथ तुलना करना स्टार्ट-अप पर डेटाबेस, और एप्लिकेशन को डेटाबेस को अपग्रेड करने के लिए डीडीएल कमांड उत्पन्न करते हैं।

मुझे लगता है कि मुझे शायद दोनों के हिस्सों को लागू करना होगा। मैं नहीं चाहता कि आवेदन हर बार जब एप्लिकेशन शुरू होता है (बहुत धीमी) संदर्भ संरचना के खिलाफ डेटाबेस को अलग करने के लिए, तो मुझे यह पता लगाने के लिए डेटाबेस संरचना संस्करण संख्या की आवश्यकता होगी कि उपयोगकर्ता पुरानी संरचना का उपयोग कर रहा है या नहीं। हालांकि, मुझे यकीन नहीं है कि मैं संरचनात्मक अपग्रेड करने के लिए प्री-लिखित स्क्रिप्ट्स पर भरोसा कर सकता हूं जब डेटाबेस को अतीत में आंशिक रूप से अपडेट किया जा सकता था या जब उपयोगकर्ता ने स्वयं डेटाबेस संरचना बदल दी हो, तो मैं एक का उपयोग करने के इच्छुक हूं वास्तविक अद्यतन के लिए संदर्भ diff।

प्रश्न का शोध करते हुए मुझे कुछ डेटाबेस संस्करण उपकरण मिल गए हैं, लेकिन वे सभी SQL सर्वर की ओर लक्षित हैं और वास्तविक एप्लिकेशन के बाहर लागू किए गए हैं। मैं एक ऐसी प्रक्रिया की तलाश में हूं जो मेरे आवेदन में कड़ाई से एकीकृत हो और इसे विभिन्न डेटाबेस आवश्यकताओं के अनुकूल बनाया जा सके (मुझे पता है कि मुझे विभिन्न लोगों के लिए डीडीएल में मतभेदों को संभालने के लिए एडाप्टर, कस्टम वंशज वर्ग या घटना कोड लिखना होगा डेटाबेस, जो मुझे परेशान नहीं करता है)।

किसी शेल्फ कि इस या उस में नाकाम रहने, किसी पर कोई विचार है करता है बंद कुछ भी पता है:

  1. एक आवेदन के अंदर एक सामान्य संबंधपरक डेटाबेस संरचना का एक संदर्भ संस्करण स्टोर करने के लिए सबसे अच्छा तरीका है ।

  2. वास्तविक डेटाबेस के संदर्भ में अंतर करने का सबसे अच्छा तरीका।

  3. डेटाबेस अद्यतन करने के लिए डीडीएल उत्पन्न करने का सबसे अच्छा तरीका।

उत्तर

2

मेरे पास है यहां एक ब्लॉग पोस्ट है कि मैं dbisam database versioning और sql server कैसे करता हूं।

महत्वपूर्ण हिस्से हैं:

क्योंकि dbisam विचारों का समर्थन नहीं करता, संस्करण संख्या डेटाबेस निर्देशिका में एक आरं फ़ाइल में (अन्य जानकारी के एक समूह के साथ साथ) संग्रहित है।

मेरे पास डेटामैड्यूल है, TdmodCheckDatabase। डेटाबेस में प्रत्येक तालिका के लिए TdbisamTable घटक है। तालिका घटक तालिका में सभी फ़ील्ड शामिल हैं और अद्यतन किया जाता है जब भी तालिका बदल जाती है।

डेटाबेस परिवर्तन करने के लिए, निम्नलिखित प्रक्रिया का इस्तेमाल किया गया था:

  1. आवेदन
  2. मेक और परीक्षण DB परिवर्तन में संस्करण संख्या बढ़ाएँ।
  3. TdmodCheckDatabase
  4. में प्रभावित तालिकाओं को अपडेट करें यदि आवश्यक हो (शायद ही कभी) TdmodCheckDatabase पर अपग्रेड क्वेरी जोड़ें। जैसे नए क्षेत्रों के मान सेट करने के लिए, या नई डेटा पंक्तियों को जोड़ने के लिए।
  5. आपूर्ति किए गए डेटाबेस उपकरण का उपयोग कर CreateDatabase इकाई स्क्रिप्ट उत्पन्न करें।
  6. अद्यतन इकाई परीक्षण नया डाटाबेस

जब आवेदन चलाया जाता है सूट करने के लिए, यह निम्न प्रक्रिया

  1. यदि कोई डेटाबेस पाया जाता है के माध्यम से चला जाता है, तो CreateDatabase इकाई को चलाने के लिए और फिर है चरण 3
  2. डेटाबेस आईएनआई फ़ाइल
  3. से वर्तमान संस्करण संख्या प्राप्त करें यदि यह अपेक्षित संस्करण संख्या से कम है तो रन CreateDatabase (किसी भी नए टेबल बनाने के लिए) चेक TdmodCheckDatabase में हर तालिका घटक लागू किसी भी तालिका रन किसी भी मैन्युअल अपग्रेड लिपियों
  4. अद्यतन डेटाबेस INI फ़ाइल

में संस्करण संख्या एक कोड नमूना है बदल जाता है

class procedure TdmodCheckDatabase.UpgradeDatabase(databasePath: string; currentVersion, newVersion: integer); 
var 
module: TdmodCheckDatabase; 
f: integer; 
begin 
module:= TdmodCheckDatabase.create(nil); 
try 
    module.OpenDatabase(databasePath); 

    for f:= 0 to module.ComponentCount -1 do 
    begin 
    if module.Components[f] is TDBISAMTable then 
    begin 
     try 
     // if we need to upgrade table to dbisam 4 
     if currentVersion <= DB_VERSION_FOR_DBISAM4 then 
      TDBISAMTable(module.Components[f]).UpgradeTable; 

     module.UpgradeTable(TDBISAMTable(module.Components[f])); 
     except 
     // logging and error stuff removed 
     end; 
    end; 
    end; 

    for f:= currentVersion + 1 to newVersion do 
    module.RunUpgradeScripts(f); 

    module.sqlMakeIndexes.ExecSQL; // have to create additional indexes manually 
finally 
    module.DBISAMDatabase1.Close; 
    module.free; 
end; 
end; 


procedure TdmodCheckDatabase.UpgradeTable(table: TDBISAMTable); 
var 
fieldIndex: integer; 
needsRestructure: boolean; 
canonical: TField; 
begin 
needsRestructure:= false; 

table.FieldDefs.Update; 

// add any new fields to the FieldDefs 
if table.FieldDefs.Count < table.FieldCount then 
begin 
    for fieldIndex := table.FieldDefs.Count to table.Fields.Count -1 do 
    begin 
    table.FieldDefs.Add(fieldIndex + 1, table.Fields[fieldIndex].FieldName, table.Fields[fieldIndex].DataType, table.Fields[fieldIndex].Size, table.Fields[fieldIndex].Required); 
    end; 
    needsRestructure:= true; 
end; 

// make sure we have correct size for string fields 
for fieldIndex := 0 to table.FieldDefs.Count -1 do 
begin 
    if (table.FieldDefs[fieldIndex].DataType = ftString) then 
    begin 
    canonical:= table.FindField(table.FieldDefs[fieldIndex].Name); 
    if assigned(canonical) and (table.FieldDefs[fieldIndex].Size <> canonical.Size) then 
    begin 
    // field size has changed 
    needsRestructure:= true; 
    table.FieldDefs[fieldIndex].Size:= canonical.Size; 
    end; 
    end; 
end; 

if needsRestructure then 
    table.AlterTable(); // upgrades table using the new FieldDef values 
end; 

procedure TdmodCheckDatabase.RunUpgradeScripts(newVersion: integer); 
begin 
case newVersion of 
    3: sqlVersion3.ExecSQL; 
    9: sqlVersion9.ExecSQL; 
    11: begin // change to DBISAM 4 
     sqlVersion11a.ExecSQL; 
     sqlVersion11b.ExecSQL; 
     sqlVersion11c.ExecSQL; 
     sqlVersion11d.ExecSQL; 
     sqlVersion11e.ExecSQL; 
     end; 
    19: sqlVersion19.ExecSQL; 
    20: sqlVersion20.ExecSQL; 
end; 
end; 
+1

एक बेहद विस्तृत और सहायक उत्तर के लिए धन्यवाद। यह एक या दो दिन होगा जब तक कि मैं इसे पच नहीं सकता। –

1

मैं क्या करता हूं डेटाबेस में संस्करण संख्या स्टोर करता है, और एप्लिकेशन में संस्करण संख्या संग्रहित करता है। हर बार मुझे डेटाबेस संरचना को बदलने की ज़रूरत है, मैं कुछ कोड डेटाबेस की संरचना अद्यतन करता हूं, और एप्लिकेशन में संस्करण संख्या बढ़ाता हूं। जब एप्लिकेशन शुरू होता है, तो यह तुलना करता है, संख्याएं, और यदि डेटाबेस संरचना और अद्यतन करने के लिए कुछ कोड चलाए जाते हैं तो डेटाबेस के संस्करण संख्या को अद्यतन करें। इस प्रकार डेटाबेस अब आवेदन के साथ अद्यतित है।मेरे कोड की तरह

if DBVersion < AppVersion then 
begin 
    for i := DBVersion+1 to AppVersion do 
    UpdateStructure(i); 
end 
else 
    if DBVersion > AppVersion then 
    raise EWrongVersion.Create('Wrong application for this database'); 

UpdateStructure कुछ वैसे ही जैसे आवश्यक कोड कुछ चलाता है:

procedure UpdateStructure(const aVersion : Integer); 
begin 
    case aVersion of 
    1 : //some db code 
    2 : //some more db code 
    ... 
    ... 
    end; 
    UpdateDatabaseVersion(aVersion); 
end; 

आप वास्तव में खरोंच से डेटाबेस बनाने के लिए एक ही कोड का उपयोग कर सकते

CreateDatabase; 
for i := 1 to AppVersion do 
    UpdateStructure(i); 
4

इसी तरह की कहानी यहां। हम एक 'सिस्टम' तालिका में एक डीबी संस्करण संख्या स्टोर करते हैं और स्टार्टअप पर जांचते हैं। (यदि तालिका/फ़ील्ड/मान मौजूद नहीं है तो हम जानते हैं कि यह संस्करण 0 है जहां हम उस बिट को जोड़ना भूल गए हैं!)

विकास के दौरान जब हमें डेटाबेस को अपग्रेड करने की आवश्यकता होती है तो हम एक डीडीएल स्क्रिप्ट लिखते हैं काम और एक बार खुश है कि यह काम कर रहा है ठीक है, यह ऐप को टेक्स्ट संसाधन के रूप में जोड़ा जाता है।

जब ऐप निर्धारित करता है कि इसे अपग्रेड करने की आवश्यकता है तो उचित संसाधन लोड करता है और इसे चलाता है। यदि इसे कई संस्करणों को अपग्रेड करने की आवश्यकता है तो इसे क्रम में प्रत्येक स्क्रिप्ट को चलाना होगा। अंत में कोड की केवल कुछ पंक्तियां बनती हैं।

मुख्य बिंदु यह है कि जीयूआई आधारित टूल का उपयोग करने के बजाय किसी विज्ञापन-शब्द या 'यादृच्छिक' तरीके से टेबल को संशोधित करने के बजाय हम वास्तव में डीडीएल को तुरंत लिखते हैं। पूर्ण अपग्रेड स्क्रिप्ट बनाने के लिए, समय आने पर यह बहुत आसान बनाता है। और संरचना diff'ing की आवश्यकता नहीं है।

2

मैं अपने डेटाबेस के लिए एडीओ का उपयोग कर रहा हूं। मैं एक संस्करण संख्या योजना का भी उपयोग करता हूं, लेकिन केवल एक सैनिटी चेक के रूप में। मेरे पास एक प्रोग्राम है जिसे मैंने विकसित किया है जो कनेक्शन का उपयोग करता है। गेटटेबल नाम और कनेक्शन। गेटफ़िल्ल्ड नाम किसी XML दस्तावेज़ के विरुद्ध किसी भी विसंगति की पहचान करने के लिए जो "मास्टर" डेटाबेस का वर्णन करता है। यदि कोई विसंगति है, तो मैं लापता फ़ील्ड बनाने के लिए उपयुक्त एसक्यूएल का निर्माण करता हूं। मैं अतिरिक्त लोगों को कभी नहीं छोड़ता।

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

मैं एक मिनी-डीबी-संस्करण भी बनाए रखता हूं, जिसे भी चेक किया जाता है क्योंकि मैं उपयोगकर्ताओं को क्लाइंट के पुराने संस्करण का उपयोग करने की अनुमति देता हूं, मैं केवल उन्हें अनुमति देता हूं एक संस्करण का उपयोग करें जो = = min-db-version और < = cur-db-version है।

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^