मैं लेन-देन डेटाबेस के लिए कुछ नया हूं और एक समस्या में आया हूं जिसे मैं समझने की कोशिश कर रहा हूं।पायथन पोस्टग्रेस कर्सर टाइमस्टैम्प समस्या
मैंने एक साधारण प्रदर्शन बनाया है जहां चेरीपी द्वारा बनाए गए प्रत्येक 5 धागे के अंदर डेटाबेस कनेक्शन संग्रहीत किया जाता है। मेरे पास एक विधि है जो डेटाबेस में संग्रहीत टाइमस्टैम्प की एक तालिका और टाइम स्टैंप का नया रिकॉर्ड जोड़ने के लिए एक बटन प्रदर्शित करती है।
तालिका में 2 फ़ील्ड हैं, एक datetime.datetime.now() के लिए एक पाइथन द्वारा पारित टाइमस्टैम्प और डेटाबेस टाइमस्टैम्प के लिए डिफ़ॉल्ट रूप से सेट()।
CREATE TABLE test (given_time timestamp,
default_time timestamp DEFAULT NOW());
मेरे पास 2 विधियां हैं जो डेटाबेस से बातचीत करती हैं। पहला नया कर्सर बनाएगा, एक नया दिया गया_टिमस्टैम्प डालें, कर्सर को प्रतिबद्ध करेगा, और इंडेक्स पेज पर वापस आ जाएगा। दूसरी विधि एक नया कर्सर बनाएगी, 10 सबसे हालिया टाइमस्टैम्प का चयन करें और कॉलर को वापस कर दें।
import sys
import datetime
import psycopg2
import cherrypy
def connect(thread_index):
# Create a connection and store it in the current thread
cherrypy.thread_data.db = psycopg2.connect('dbname=timestamps')
# Tell CherryPy to call "connect" for each thread, when it starts up
cherrypy.engine.subscribe('start_thread', connect)
class Root:
@cherrypy.expose
def index(self):
html = []
html.append("<html><body>")
html.append("<table border=1><thead>")
html.append("<tr><td>Given Time</td><td>Default Time</td></tr>")
html.append("</thead><tbody>")
for given, default in self.get_timestamps():
html.append("<tr><td>%s<td>%s" % (given, default))
html.append("</tbody>")
html.append("</table>")
html.append("<form action='add_timestamp' method='post'>")
html.append("<input type='submit' value='Add Timestamp'/>")
html.append("</form>")
html.append("</body></html>")
return "\n".join(html)
@cherrypy.expose
def add_timestamp(self):
c = cherrypy.thread_data.db.cursor()
now = datetime.datetime.now()
c.execute("insert into test (given_time) values ('%s')" % now)
c.connection.commit()
c.close()
raise cherrypy.HTTPRedirect('/')
def get_timestamps(self):
c = cherrypy.thread_data.db.cursor()
c.execute("select * from test order by given_time desc limit 10")
records = c.fetchall()
c.close()
return records
if __name__ == '__main__':
cherrypy.config.update({'server.socket_host': '0.0.0.0',
'server.socket_port': 8081,
'server.thread_pool': 5,
'tools.log_headers.on': False,
})
cherrypy.quickstart(Root())
मैं given_time और default_time timestamps केवल एक दूसरे से दूर कुछ माइक्रोसेकंड होने की अपेक्षा करेंगे। हालांकि मुझे कुछ अजीब व्यवहार मिल रहा है। यदि मैं प्रत्येक कुछ सेकंड में टाइमस्टैम्प जोड़ता हूं, तो डिफ़ॉल्ट_टाइम दिए गए समय से कुछ माइक्रोसेकंड नहीं है, लेकिन आमतौर पर पिछले दिए गए समय से कुछ माइक्रोसेकंड बंद हो जाता है।
Given Time Default Time 2009-03-18 09:31:30.725017 2009-03-18 09:31:25.218871 2009-03-18 09:31:25.198022 2009-03-18 09:31:17.642010 2009-03-18 09:31:17.622439 2009-03-18 09:31:08.266720 2009-03-18 09:31:08.246084 2009-03-18 09:31:01.970120 2009-03-18 09:31:01.950780 2009-03-18 09:30:53.571090 2009-03-18 09:30:53.550952 2009-03-18 09:30:47.260795 2009-03-18 09:30:47.239150 2009-03-18 09:30:41.177318 2009-03-18 09:30:41.151950 2009-03-18 09:30:36.005037 2009-03-18 09:30:35.983541 2009-03-18 09:30:31.666679 2009-03-18 09:30:31.649717 2009-03-18 09:30:28.319693
फिर भी, अगर मैं हर एक मिनट में के बारे में एक नया टाइमस्टैम्प जोड़ने के लिए, दोनों given_time और default_time केवल अपेक्षा के अनुरूप बंद कुछ माइक्रोसेकंड हैं। हालांकि, 6 वां टाइमस्टैम्प सबमिट करने के बाद (थ्रेड + 1 की संख्या) डिफ़ॉल्ट_टाइम पहले दिए गए टाइमटाम्प से कुछ माइक्रोसेकंड बंद है।
Given Time Default Time 2009-03-18 09:38:15.906788 2009-03-18 09:33:58.839075 2009-03-18 09:37:19.520227 2009-03-18 09:37:19.520293 2009-03-18 09:36:04.744987 2009-03-18 09:36:04.745039 2009-03-18 09:35:05.958962 2009-03-18 09:35:05.959053 2009-03-18 09:34:10.961227 2009-03-18 09:34:10.961298 2009-03-18 09:33:58.822138 2009-03-18 09:33:55.423485
हालांकि मैं स्पष्ट रूप से प्रत्येक उपयोग के बाद कर्सर को बंद कर रहा हूँ, ऐसा लगता है कि पिछले कर्सर अभी भी पुन: उपयोग किया जा रहा है। यह कैसे संभव है यदि मैं कर्सर को बंद कर रहा हूं और इसके बाद हर बार एक नया कर्सर बना रहा हूं? क्या कोई यहां बता सकता है कि यहां क्या हो रहा है? एक जवाब के लिए
करीब:
मैं एक cursor.connection.commit (जोड़ दिया है) get_timestamps विधि करने के लिए और कहा कि अब मुझे टाइमस्टैम्प के साथ सही आंकड़ा देता है। क्या कोई समझा सकता है कि मुझे कर्सर को कॉल करने की आवश्यकता क्यों हो सकती है .connection.commit() जब मैं बस इतना कर रहा हूं तो एक चयन है? मैं अनुमान लगा रहा हूं कि हर बार जब मैं कर्सर प्राप्त करता हूं, तो एक लेनदेन शुरू होता है (या मौजूदा लेनदेन इकाई के साथ जारी रहता है)। क्या ऐसा करने का कोई बेहतर तरीका है या क्या मैं हर बार कर्सर प्राप्त करता हूं, इस पर ध्यान दिए बिना कि मैं उस कर्सर के साथ क्या करता हूं?
इसे समझाने के लिए धन्यवाद। मैंने अभी तक आपके सुझावों का परीक्षण नहीं किया है, लेकिन मैंने यह बताने का सबसे अच्छा काम करने के लिए अपना जवाब स्वीकार कर लिया है कि टाइमस्टैम्प गलत क्यों होगा। हालांकि, अब मैं सोच रहा हूं कि कोई तरीका है कि मैं एक लेनदेन शुरू किए बिना कर्सर बना सकता हूं। – adam
आप साइकोप 2 को लेनदेन अलगाव स्तर 'ISOLATION_LEVEL_AUTOCOMMIT' पर सेट कर सकते हैं, जो आदेश जारी किए जाने पर लेनदेन शुरू नहीं करेगा। मुझे नहीं पता कि परिवर्तन कितना व्यापक होगा, यद्यपि; ऐसा करने से लेन-देन का उपयोग करने वाले अन्य प्रश्नों को तोड़ सकता है। – kquinn