2025, Oct 15 16:02
PyInstaller पैक .exe आउटपुट क्यों नहीं दिखा रहा: psycopg2 से pg8000 तक समाधान
Python स्क्रिप्ट PyInstaller से .exe बनने पर आउटपुट नहीं देती? PostgreSQL में psycopg2 की जगह pg8000 अपनाकर समस्या सुलझाएँ; डिबग प्रिंट व पैकेजिंग टिप्स.
PyInstaller के साथ एक साधारण PostgreSQL क्लाइंट स्क्रिप्ट को पैक करना आमतौर पर सीधा होना चाहिए। फिर भी एक आम फँसाव कुछ यूँ दिखता है: .py ठीक चलता है, PyInstaller बिल्ड कोई त्रुटि नहीं दिखाता, executable शुरू होता है… और बिल्कुल भी आउटपुट नहीं देता। अगर आप डेटाबेस से क्वेरी कर रहे हैं और बस कंसोल में पंक्तियाँ छपने की उम्मीद है, तो ऐसे मौन रन खास तौर पर उलझाते हैं।
समस्या की स्थिति
नीचे दिया गया स्क्रिप्ट PostgreSQL से जुड़ता है, ईमेल चुनता है और परिणाम प्रिंट करता है। Python फ़ाइल के रूप में यह सही चलता है; लेकिन PyInstaller से बने .exe में न कोई परिणाम दिखता है और न कोई त्रुटि।
import psycopg2
try:
    db_link = psycopg2.connect(
        dbname="xxxx",
        user="xxxx",
        password="xxxx",
        host="postgresql-xxxx-xxxx.xxxx.xxxx",
        port="xxxx"
    )
    cur = db_link.cursor()
    cur.execute("SELECT email FROM membre")
    result_rows = cur.fetchall()
    for rec in result_rows:
        print(rec)
except Exception as err:
    print(f"Une erreur est survenue : {err}")
finally:
    if cur:
        cur.close()
    if db_link:
        db_link.close()
पैकेजिंग के लिए इस्तेमाल की गई कमांड ने संबंधित मॉड्यूल को स्पष्ट रूप से शामिल करने की कोशिश की। बिल्ड बिना त्रुटियों के पूरा हो गया, फिर भी executable ने कोई आउटपुट नहीं दिया।
pyinstaller --onefile --hidden-import=psycopg2 --hidden-import=psycopg2._psycopg --hidden-import=psycopg2.extensions --hidden-import=psycopg2.extras --hidden-import=sqlalchemy.dialects.postgresql --hidden-import=sqlalchemy.dialects.postgresql.psycopg2 creation_userform_sans_sql.py
असल में हो क्या रहा है
न तो बिल्ड के समय कोई त्रुटि आती है और न ही executable शुरू होने में समस्या, लेकिन वह कुछ प्रिंट नहीं करता। टर्मिनल से चलाने पर भी यही व्यवहार दिखता है: न traceback, न आउटपुट। ऐसी स्थिति में वजहों को गड्डमड्ड करना आसान है, पर यहाँ जो एकमात्र पुष्ट अवलोकन है, वह यह कि PyInstaller से पैक करने पर रनटाइम में आउटपुट गायब है, जबकि वही स्क्रिप्ट साधारण Python के रूप में ठीक काम करती है।
जब executable खामोश लगे, तो यह जाँचना उपयोगी होता है कि प्रवाह कहाँ रुक रहा है और कौन‑कौन से मान खेल में हैं। इसका सरल तरीका है हल्का इंस्ट्रूमेंटेशन जोड़ना—कुछ print() स्टेटमेंट्स—और बाहर निकलने से पहले थोड़ी देर रुकना, ताकि कंसोल विंडो पर्याप्त देर तक खुली रहे और आउटपुट पढ़ा जा सके। यह भी वाजिब है कि क्वेरी शून्य पंक्तियाँ लौटा रही हो; पहली sanity जाँच के तौर पर row count देख लें। दूसरों की सलाह के अनुसार PyInstaller की डिबग विकल्पों को सक्षम करना या optimization बदलकर देखना भी मददगार हो सकता है कि कहीं पैकेजर रनटाइम व्यवहार तो नहीं बदल रहा। ये जाँचें प्रोग्राम की तर्कशक्ति नहीं बदलतीं, लेकिन यह दिखा सकती हैं कि अपेक्षा के मुताबिक कोड चला या नहीं।
न्यूनतम जाँच: निष्पादन प्रवाह की पुष्टि
नीचे दिया गया रूप वही तर्क रखता है और पैक किए गए रूप में निष्पादन देखने के लिए कुछ संकेत जोड़ता है। यह पैकेजिंग समस्या को ठीक नहीं करता; बस .exe चलने पर वास्तव में क्या हो रहा है, इसे पुख्ता करने में मदद करता है।
import psycopg2
import time
try:
    print("start: connecting")
    db_link = psycopg2.connect(
        dbname="xxxx",
        user="xxxx",
        password="xxxx",
        host="postgresql-xxxx-xxxx.xxxx.xxxx",
        port="xxxx"
    )
    print("connected: opening cursor")
    cur = db_link.cursor()
    print("executing query")
    cur.execute("SELECT email FROM membre")
    print("fetching rows")
    result_rows = cur.fetchall()
    print(f"row count: {len(result_rows)}")
    for rec in result_rows:
        print(rec)
    print("done; sleeping briefly to keep console visible")
    time.sleep(10)
except Exception as err:
    print(f"Une erreur est survenue : {err}")
    time.sleep(10)
finally:
    if cur:
        cur.close()
    if db_link:
        db_link.close()
जो समाधान कारगर रहा
PostgreSQL ड्राइवर बदलने से पैकेजिंग की दिक्कत दूर हो गई: psycopg2 की जगह pg8000 इस्तेमाल करने पर बना .exe, .py की तरह ही चला और अपेक्षित आउटपुट दिया। इस नतीजे के लिए एप्लिकेशन लॉजिक में कोई अतिरिक्त बदलाव जरूरी नहीं पड़ा। बिल्ड बिना त्रुटियों के पूरा हुआ और पैक किया गया executable मनचाहे अनुसार परिणाम प्रिंट करता रहा।
यह क्यों महत्वपूर्ण है
पैकेजिंग के बाद रनटाइम पर बिना आवाज़ के असफल होना बेहद समयखाऊ होता है, क्योंकि यह बताने वाला संकेत लगभग नहीं मिलता कि गड़बड़ी कहाँ है। आपका एप्लिकेशन अगर I/O पर निर्भर है (डेटाबेस एक्सेस, नेटवर्क कॉल), तो ड्राइवर या पैकेजिंग की हल्की‑सी बारीकी भी दिखने वाला आउटपुट दबा सकती है। यह जानना कि PostgreSQL मॉड्यूल बदलने से इस परिदृश्य में व्यवहार सामान्य हो गया, आपको एक ठोस रास्ता देता है—जब लक्षण वही हों: .py काम करता है, PyInstaller बिल्ड में त्रुटि नहीं, .exe चलता है पर कुछ प्रिंट नहीं करता।
व्यावहारिक बातें
यदि PyInstaller से बना executable कुछ नहीं करता जबकि साधारण स्क्रिप्ट ठीक चलती है, तो print() और थोड़े विराम के साथ निष्पादन प्रवाह की पुष्टि करें, ताकि गायब होती कंसोल विंडो या खाली परिणाम‑समूह जैसी बातों को खारिज किया जा सके। अगर बिल्ड अब भी खामोशी से चल रहा हो, तो PostgreSQL क्लाइंट मॉड्यूल बदलकर देखें। इस मामले में, psycopg2 से pg8000 पर जाने से .exe का व्यवहार .py जैसा ही हो गया। ज़रूरत पड़े तो PyInstaller की डिबग सेटिंग्स और अलग‑अलग optimization स्तरों को आज़माएँ, ताकि देखें कि पैकेजर रनटाइम को प्रभावित तो नहीं कर रहा; जाँच के दौरान मूल स्क्रिप्ट को अपरिवर्तित रखें।
मुख्य सलाह सरल है: समस्या आपके कोड में है या पैकेजर द्वारा बनाए गए रनटाइम परिवेश में—इसे अलग‑थलग करें। यदि आपकी लॉजिक सही है और पैकेजिंग के बाद वही प्रोग्राम किसी दूसरे PostgreSQL मॉड्यूल के साथ बिना बदले काम कर जाता है, तो आपके पास एप्लिकेशन को फिर से लिखे बिना आगे बढ़ने का व्यावहारिक रास्ता है।