2025, Oct 07 11:31
एक ही PostgreSQL URI से read-only टॉगल कर Polars में ADBC और connectorx चलाएँ
जानें कैसे PostgreSQL और Polars में एक ही URI से read-only ट्रांज़ैक्शन टॉगल करें: ADBC इसे मानता है, connectorx में options हटाकर पोर्टेबल समाधान पाएं आसानी से.
PostgreSQL और Polars के बीच डेटा ले जाते समय, अक्सर एक ही कनेक्शन URI को मानक बनाकर अलग-अलग इंजनों में दोबारा उपयोग करने का मन होता है। अड़चन URI में PostgreSQL options के जरिए read-only लागू करने पर आती है। adbc इंजन default_transaction_read_only=True जैसी options वाले URI को स्वीकार करता है, जबकि connectorx अतिरिक्त पैरामीटर नहीं मानता। मकसद है एक ही URI रखना और read-only को जरूरत के अनुसार चालू/बंद करना, वह भी दो अलग-अलग संस्करण संभाले बिना।
समस्या की रूपरेखा
Polars pl.read_database_uri के जरिए इंजनों connectorx या adbc से पढ़ सकता है, और DataFrame.write_database के जरिए इंजनों adbc या sqlalchemy से लिख सकता है। read-only ट्रांज़ैक्शन फ्लैग के साथ PostgreSQL URI कुछ ऐसा होता है:
"postgresql://scott:tiger@localhost:5432/mydatabase?options=-c%20default_transaction_read_only%3DTrue"यहां अहम हिस्सा है default_transaction_read_only=True। दिक्कत यह है कि adbc इस options वाले हिस्से को स्वीकार करता है, लेकिन connectorx अतिरिक्त पैरामीटर सेट करने की अनुमति नहीं देता।
विसंगति दिखाने वाला न्यूनतम उदाहरण
import polars as pl
uri_with_ro = (
    r"postgresql://user:pass@localhost:5432/dbname"
    r"?options=-c%20default_transaction_read_only%3DTrue"
)
# यह अलग-अलग इंजनों के लिए उसी URI का उपयोग करता है।
# adbc options वाले हिस्से को स्वीकार करता है।
pl.read_database_uri(
    query="SELECT 1",
    uri=uri_with_ro,
    engine="adbc",
)
# connectorx URI में अतिरिक्त पैरामीटर स्वीकार नहीं करता।
pl.read_database_uri(
    query="SELECT 1",
    uri=uri_with_ro,
    engine="connectorx",
)असल में हो क्या रहा है
इंजनों का व्यवहार अलग-अलग है। adbc उस URI के साथ काम करता है जिसमें ?options=-c%20default_transaction_read_only%3D... शामिल है, जबकि connectorx अतिरिक्त पैरामीटर नहीं मानता। नतीजा यह कि options वाला एक ही URI बिना बदलाव के दोनों इंजनों में पोर्टेबल नहीं है।
व्यावहारिक समाधान: केवल connectorx के लिए options हटाएँ
सबसे आसान तरीका यह है कि read-only स्विच वाला एक कैनॉनिकल URI बनाएँ, और सिर्फ तब ?options वाला हिस्सा प्रोग्रामेटिकली हटा दें जब इंजन connectorx हो। इससे इंजन-विशिष्ट हैंडलिंग एक ही जगह रहती है और एक फ्लैग से read-only को टॉगल किया जा सकता है।
import polars as pl
ro_flag = "False"  # या "True"
dsn_uri = (
    rf"postgresql://username:password@host:port/database"
    rf"?options=-c%20default_transaction_read_only%3D{ro_flag}"
)
def run_query_via_uri(sql: list[str] | str, dsn: str, backend: str, **extras):
    if backend == "connectorx":
        cut = dsn.find("?options", dsn.rfind("/"))
        dsn = dsn[:cut] if cut != -1 else dsn
    return pl.read_database_uri(query=sql, uri=dsn, engine=backend, **extras)
# इंजनों के पार एकीकृत reads
run_query_via_uri(
    "SELECT * FROM public.a_tbl",
    dsn=dsn_uri,
    backend="adbc",
)
run_query_via_uri(
    "SELECT * FROM public.a_tbl",
    dsn=dsn_uri,
    backend="connectorx",
)
# इंजनों के पार एकीकृत लेखन
# dataset एक मौजूदा Polars DataFrame है
dataset.write_database(
    "public.a_tbl",
    connection=dsn_uri,
    engine="adbc",
    if_table_exists="append",
)
dataset.write_database(
    "public.a_tbl",
    connection=dsn_uri,
    engine="sqlalchemy",
    if_table_exists="append",
)यह क्यों मायने रखता है
एक ही URI रखने से इंटीग्रेशन कोड सरल होता है और पढ़ने व लिखने के रास्तों में कॉन्फ़िगरेशन के बिखराव की आशंका घटती है। Polars में pl.read_database_uri engine आर्ग्युमेंट से संचालित होता है, और DataFrame.write_database भी इंजन बदल सकता है। प्रति-इंजन कनेक्शन स्ट्रिंग में होने वाले बदलावों को केंद्रीकृत रखने से कॉलिंग कोड साफ रहता है और कोڈबेस में इधर-उधर फैली अस्थायी शाखाएँ नहीं बनतीं।
मुख्य बातें
यदि आपको अपनी कनेक्शन स्ट्रिंग में PostgreSQL के read-only सेमान्टिक्स चाहिए, तो adbc options वाले हिस्से को सीधे स्वीकार करता है, जबकि connectorx अतिरिक्त पैरामीटर नहीं मानता। एक ऐसा URI बनाएँ जिसमें default_transaction_read_only एन्कोड हो, और सिर्फ connectorx के लिए options को हटा दें। इस तरह आप एक ही स्विच से read-only टॉगल कर पाएँगे और उसी स्ट्रिंग को adbc या connectorx के जरिए पढ़ने, तथा adbc या sqlalchemy के जरिए लिखने में दोबारा उपयोग कर पाएँगे—बिना कई कनेक्शन टेम्पलेट्स संभाले।