2012-05-31 14 views
10

मैं पाइथन में ऑब्जेक्ट दृढ़ता को लागू करने के तरीकों के बारे में सलाह ले रहा हूं। अधिक सटीक होने के लिए, मैं एक पायथन ऑब्जेक्ट को इस तरह से फ़ाइल में लिंक करने में सक्षम होना चाहता हूं कि किसी भी पायथन प्रक्रिया जो उस फ़ाइल का प्रतिनिधित्व खोलती है, वही जानकारी साझा करती है, कोई भी प्रक्रिया अपनी वस्तु को बदल सकती है और परिवर्तन प्रचारित होंगे अन्य प्रक्रियाएं, और यहां तक ​​कि यदि ऑब्जेक्ट को "संग्रहित" करने वाली सभी प्रक्रियाएं बंद हैं, तो फ़ाइल रहेगी और दूसरी प्रक्रिया द्वारा फिर से खोली जा सकती है।पायथन ऑब्जेक्ट दृढ़ता

मुझे पाइथन - anydbm, pickle, और shelve के वितरण में इसके लिए तीन मुख्य उम्मीदवार मिले (डीबीएम सही साबित हुआ, लेकिन यह केवल यूनिक्स है, और मैं विंडोज़ पर हूं)। हालांकि, वे सभी खामियों है:

  • anydbm केवल स्ट्रिंग मूल्यों की एक शब्दकोश (मैं हालांकि आदर्श मैं एक कोशिश करेगी, जो सभी के स्ट्रिंग कुंजी और स्ट्रिंग मान हो शब्दकोशों की एक सूची संग्रहीत करने की मांग कर रहा हूँ, संभाल कर सकते हैं बिना किसी प्रकार के प्रतिबंध के मॉड्यूल)
  • शेल्व की आवश्यकता है कि परिवर्तन प्रसार से पहले एक फ़ाइल फिर से खोला जाए - उदाहरण के लिए, यदि दो प्रक्रियाएं ए और बी एक ही फ़ाइल लोड करती हैं (एक शेल्व खाली सूची युक्त), और ए एक आइटम को जोड़ता है सूची और कॉल सिंक(), बी अभी भी सूची को रिक्त होने तक खाली होने के रूप में दिखाई देगी।
  • अचार (मॉड्यूल जो मैं वर्तमान में अपने परीक्षण कार्यान्वयन के लिए उपयोग कर रहा हूं) में समान "रीलोड आवश्यकता" शेल्फ के रूप में है, और पिछले डेटा को ओवरराइट भी नहीं करता है - यदि प्रक्रिया ए एक फ़ाइल पर पंद्रह खाली तारों को डंप करता है, और फिर स्ट्रिंग ' हैलो ', प्रक्रिया बी को' हैलो 'स्ट्रिंग प्राप्त करने के लिए फ़ाइल को सोलह बार लोड करना होगा। मैं फिलहाल फाइल के अंत तक ("स्लेट साफ़ करने से पहले स्लीप क्लीन को मिटाकर") के बार-बार पढ़ने के साथ किसी भी लिखने के ऑपरेशन से पहले इस समस्या से निपट रहा हूं, और फ़ाइल के अंत तक हर पठन ऑपरेशन दोहराकर, लेकिन मुझे लगता है कि वहां होना चाहिए एक बेहतर तरीका है।

मेरे आदर्श मॉड्यूल ('ए >>> "प्रक्रिया एक द्वारा निष्पादित का प्रतिनिधित्व कोड, और" बी >>> "कोड प्रक्रिया बी द्वारा निष्पादित साथ) के रूप में व्यवहार करते हैं जाएगा:

A>>> import imaginary_perfect_module as mod 
B>>> import imaginary_perfect_module as mod 
A>>> d = mod.load('a_file') 
B>>> d = mod.load('a_file') 
A>>> d 
{} 
B>>> d 
{} 
A>>> d[1] = 'this string is one' 
A>>> d['ones'] = 1 #anydbm would sulk here 
A>>> d['ones'] = 11 
A>>> d['a dict'] = {'this dictionary' : 'is arbitrary', 42 : 'the answer'} 
B>>> d['ones'] #shelve would raise a KeyError here, unless A had called d.sync() and B had reloaded d 
11 #pickle (with different syntax) would have returned 1 here, and then 11 on next call 
(etc. for B) 

मैं अपने स्वयं के मॉड्यूल को बनाकर इस व्यवहार को प्राप्त कर सकता है जो अचार का उपयोग करता है, और डंप और लोड व्यवहार को संपादित करता है ताकि वे उपरोक्त वर्णित बार-बार पढ़ने का उपयोग कर सकें - लेकिन मुझे यह विश्वास करना मुश्किल लगता है कि यह समस्या कभी नहीं हुई है, और इसे ठीक किया गया है , पहले और अधिक प्रतिभाशाली प्रोग्रामर। इसके अलावा, ये बार-बार पढ़ना मेरे लिए अक्षम लगता है (हालांकि मुझे यह स्वीकार करना होगा कि ऑपरेशन जटिलता का मेरा ज्ञान सीमित है, और यह संभव है कि ये बार-बार पढ़े "दृश्यों के पीछे" चल रहे हों, अन्यथा जाहिर तौर पर शेल्व जैसे चिकनी मॉड्यूल)। इसलिए, मैंने निष्कर्ष निकाला है कि मुझे कुछ कोड मॉड्यूल याद आना चाहिए जो मेरे लिए समस्या का समाधान करेगा। अगर कोई मुझे सही दिशा में इंगित कर सकता है, या कार्यान्वयन के बारे में सलाह दे सकता है तो मैं आभारी रहूंगा।

+4

'मोंगो-db' करने के लिए एक दृश्य प्रदान करें। यह उपरोक्त आपके उदाहरण के रूप में पूरी तरह से भाषा में एकीकृत नहीं है, लेकिन यह आपको फाइल सिस्टम को चुनने और ताले के बारे में स्मार्ट होने के मुकाबले ज्यादा मजबूत और सहिष्णु डेटाबेस प्रदान करेगा। – slezica

उत्तर

11

इसके बजाय ZODB (ज़ोप ऑब्जेक्ट डेटाबेस) का उपयोग करें। Zeo साथ समर्थन से यह आपके आवश्यकताओं को पूरा:

  • पायथन के लिए पारदर्शी हठ वस्तुओं

    ZODB अचार का उपयोग करता है कुछ भी है कि अचार करने योग्य एक ZODB वस्तु की दुकान में संग्रहित किया जा सकता है, तो नीचे।

  • (savepoints सहित)
  • पूर्ण एसिड-संगत लेनदेन समर्थन

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

ZODB एक दशक से अधिक के आसपास किया गया है अब, तो आप सही इस समस्या surmising में पहले से ही से पहले हल किया गया है कर रहे हैं। :-)

ZODB चलो आप स्टोरेज में प्लग करते हैं; सबसे आम प्रारूप फ़ाइलस्टॉरेज है, जो बड़ी वस्तुओं के लिए एक वैकल्पिक ब्लॉब स्टोरेज के साथ एक डेटा.एफएस में सब कुछ संग्रहीत करता है।

कुछ ZODB स्टोरेज कार्यक्षमता जोड़ने के लिए दूसरों के चारों ओर रैपर हैं; उदाहरण के लिए डेमोस्टॉरेज यूनिट परीक्षण और प्रदर्शन सेटअप की सुविधा के लिए स्मृति में परिवर्तन रखता है (पुनरारंभ करें और आपके पास फिर से साफ़ स्लेट है)। पहले स्टोरेज आपको समय में एक खिड़की देता है, केवल से पहले लेनदेन से डेटा लौटाता है। उत्तरार्द्ध मेरे लिए खोए गए डेटा को पुनर्प्राप्त करने में महत्वपूर्ण भूमिका निभाता है।

ZEO ऐसी प्लगइन है जो क्लाइंट-सर्वर आर्किटेक्चर पेश करती है। जेईईओ का उपयोग करने से आप एक समय में कई प्रक्रियाओं से दिए गए स्टोरेज तक पहुंच सकते हैं; यदि आपको केवल एक प्रक्रिया से बहु-थ्रेडेड एक्सेस की आवश्यकता है तो आपको इस परत की आवश्यकता नहीं होगी।

इसे RelStorage के साथ हासिल किया जा सकता है, जो पोस्टग्रेएसक्यूएल, माईएसQL या ओरेकल जैसे संबंधपरक डेटाबेस में ZODB डेटा संग्रहीत करता है।

+0

ZODB ठीक वैसे ही लगता है जो मैं चाहता हूं (और RelStorage भविष्य के लिए जांच करने के लिए कुछ दिलचस्प लगता है) - धन्यवाद! मैं इसका परीक्षण करूंगा और उत्तर के रूप में इसे चिह्नित करने के लिए वापस लौटूंगा यदि यह मेरे लिए काम करता है। – scubbo

+0

बहुत बढ़िया, सलाह के लिए धन्यवाद! – scubbo

+0

ऐसा लगता है कि मैं भी क्या चाहता हूं; क्या शेल्फ प्रदान करता है। – fatuhoku

2
शुरुआती के लिए

, आप बंदरगाह कर सकते हैं इस तरह ZODB डेटाबेस के लिए अपने टांड़ डेटाबेस:

#!/usr/bin/env python 
import shelve 
import ZODB, ZODB.FileStorage 
import transaction 
from optparse import OptionParser 
import os 
import sys 
import re 

reload(sys) 
sys.setdefaultencoding("utf-8") 

parser = OptionParser() 

parser.add_option("-o", "--output", dest = "out_file", default = False, help ="original shelve database filename") 
parser.add_option("-i", "--input", dest = "in_file", default = False, help ="new zodb database filename") 

parser.set_defaults() 
options, args = parser.parse_args() 

if options.in_file == False or options.out_file == False : 
    print "Need input and output database filenames" 
    exit(1) 

db = shelve.open(options.in_file, writeback=True) 
zstorage = ZODB.FileStorage.FileStorage(options.out_file) 
zdb = ZODB.DB(zstorage) 
zconnection = zdb.open() 
newdb = zconnection.root() 

for key, value in db.iteritems() : 
    print "Copying key: " + str(key) 
    newdb[key] = value 

transaction.commit() 
संबंधित मुद्दे