स्कीमा डेटाबेस के लिए ओपन-सोर्स अप्लाई क्लाइंट। इसे किसी भी ऐसी मशीन पर चलाएँ जो आपके अपने PostgreSQL तक पहुँच सके, एक बार पेयर करें, और यह उस डेटाबेस को आपके एनरिचमेंट के साथ कन्वर्ज्ड रखता है — एक स्नैपशॉट से बूटस्ट्रैप करके, फिर एक ही आउटबाउंड WebSocket पर लाइव डेल्टा फ़ीड लागू करके। आपकी कनेक्शन स्ट्रिंग कभी उस मशीन से बाहर नहीं जाती।
हर statement रिविज़न-गार्डेड है, इसलिए दोबारा डिलीवर हुआ batch वही rows पर कन्वर्ज हो जाता है। कोई SQL error batch को रोलबैक कर देता है और रोक देता है — कोई poison डेल्टा चुपचाप स्किप नहीं होता।
क्लाइंट स्टेट खींचता है, ऑपरेशन नहीं: प्रत्येक डेल्टा एक बदले हुए entity के लिए पूरी वर्तमान पंक्ति(यों) को एक idempotent INSERT … ON CONFLICT … DO UPDATE के रूप में ले जाता है, इसलिए कोई batch छूट जाने पर भी टारगेट कन्वर्ज हो जाता है।
Database syncs को कई तरीकों से उपयोग किया जा सकता है — n8n, Make.com, MCP, रॉ वेबहुक्स, या REST डेल्टा फ़ीड। sync क्लाइंट पूरी तरह स्वचालित रास्ता है: बनाने में सबसे कम और लीक होने में सबसे कम।
कोई n8n scenario नहीं, कोई cron नहीं, कोई ग्लू कोड नहीं। एक बार पेयर करें और यह snapshot से बूटस्ट्रैप हो जाता है, फिर हर डेल्टा को आते ही लागू करता है।
कनेक्शन स्ट्रिंग कमांड लाइन पर पास की जाती है या स्थानीय रूप से mode-600 में संग्रहीत होती है — इसे कभी भी Entity Enricher को नहीं भेजा जाता। क्लाइंट केवल बाहर की ओर कनेक्ट होता है।
हर डेल्टा एक idempotent, रिविज़न-गार्डेड upsert है। अगर क्लाइंट batch के बीच में बंद हो जाए, तो lease खत्म होने के बाद batch फिर से डिलीवर होता है और दोबारा लागू करने पर वही rows पर कन्वर्ज हो जाता है।
SQL एरर पूरे बैच को रोलबैक कर देता है और विफल डेल्टा की रिपोर्ट करता है। सर्वर उस एनरिचमेंट के पूरे बैच को क्वारंटीन कर देता है और कतार को उसके बिना दोबारा पुश करता है, इसलिए क्लाइंट जुड़ा रहता है और लागू करता रहता है — एक खराब रो अपने पीछे की हर चीज़ को नहीं अटका सकती, और क्वारंटीन किया गया काम तब तक सूचीबद्ध रहता है जब तक आप उसे निपटा न लें।
पहले किसी स्कीमा पर एक डेटाबेस रजिस्टर करें, फिर एक क्लाइंट पेयर करें और उसे ऐसी मशीन पर चलाएँ जो आपके डेटाबेस तक पहुँच सके।
Database Sync पेज पर, जिस स्कीमा को मिरर करना है उस पर एक डेटाबेस रजिस्टर करें और उसकी डेटाबेस कीज़ की समीक्षा करें। पूरे मॉडल के लिए Database Sync देखें। यह चरण वह लक्ष्य डायलेक्ट घोषित करता है जिसे क्लाइंट लागू करेगा।
इसे टर्मिनल में पेस्ट करें। स्क्रिप्ट इंस्टॉल करने से पहले एक cosign सिग्नेचर को वेरिफ़ाई करती है।
curl -fsSL https://entityenricher.ai/install-eedatabase.sh | sh
Windows: iwr -useb https://entityenricher.ai/install-eedatabase.ps1 | iex। या Releases से एक साइन की गई बाइनरी डाउनलोड करें, या सोर्स से बिल्ड करें (Go ≥ 1.23): go build -o ee-database .
सोर्स और साइन किए गए रिलीज़ TOT-Concept/ee-database (MIT) पर उपलब्ध हैं।
ee-database pair चलाएँ। /database/connect पर एक ब्राउज़र टैब खुलता है जिसमें एक छोटा कोड होता है — उसकी पुष्टि करें, और चुनें कि यह क्लाइंट किस डेटाबेस को sync करे।
ee-database pair --server https://entityenricher.ai Open this URL in your browser to confirm pairing: https://entityenricher.ai/database/connect?code=7QX-KP2 Code: 7QX-KP2 Waiting for confirmation...
टोकन पसंद करेंगे? Database Sync पेज पर एक जारी करें (Sync client → Pair a client) और उसे सीधे पास करें: ee-database pair --server … <refresh-token>।
पहली बार चलने पर क्लाइंट .sql snapshot फ़ेच करके लागू करता है, फिर कनेक्ट करके deltas स्ट्रीम करता है। --save-dsn कनेक्शन स्ट्रिंग को लोकली स्टोर करता है ताकि बाद के रन में कोई आर्गुमेंट न लगे।
हर रन लॉगिन के provisioning अधिकारों (create database, DDL, DML) की स्वयं जाँच करता है और परिणाम को Sync क्लाइंट कार्ड पर रिपोर्ट करता है, ताकि डेल्टा लागू होने में विफल होने से पहले कोई गायब grant दिखाई दे। यदि अभी तक कोई लिंक किया गया schema प्रकाशित नहीं हुआ है, तो क्लाइंट कनेक्टेड रहता है और प्रतीक्षा करता है — पहला प्रकाशन स्वयं फ़ीड शुरू कर देता है, किसी रीस्टार्ट की ज़रूरत नहीं।
ee-database run --dsn "postgres://user:pass@localhost:5432/mydb" --save-dsn
“Next to” का मतलब है नेटवर्क के पास, डेटाबेस सर्वर पर नहीं: कोई भी मशीन या container जो DSN तक पहुँच सकती है, काम करती है — इसमें cloud-managed PostgreSQL (Azure, OVHcloud, AWS RDS…) भी शामिल है, जो आमतौर पर TLS लागू करता है: …/mydb?sslmode=require।
एक ही मशीन पर कई डेटाबेस? sync host पेयरिंग की प्रक्रिया को एक स्तर ऊपर ले जाता है: मशीन को एक बार पेयर करें, और उसे आप जो भी database sync असाइन करेंगे वह अपने आप क्लेम, प्रोविज़न और सिंक होता रहेगा — नया sync रजिस्टर करने के लिए दोबारा टर्मिनल सेशन की ज़रूरत कभी नहीं पड़ती। इसके लिए क्लाइंट 1.5.0 या बाद का संस्करण चाहिए, जो प्रति मशीन नहीं बल्कि प्रति सर्वर एक बार पेयर करता है — इसलिए एक ही होस्ट कई Entity Enricher इंस्टेंस को साथ-साथ सेवा दे सकता है।
Database Sync पेज पर, Sync hosts टूलबार बटन पर क्लिक करें और मशीन के नाम पर एक होस्ट जोड़ें। एक बार उपयोग होने वाला पेयरिंग टोकन ठीक एक ही बार दिखता है, जो निर्देशित सेटअप चरणों सहित कॉपी-पेस्ट करने योग्य host pair कमांड में शामिल होता है।
उस मशीन पर कमांड चलाएँ जो आपके डेटाबेस सर्वर तक पहुँच सकती है। --dsn एक बेस कनेक्शन स्ट्रिंग है जो सर्वर को नाम देती है, बिना किसी डेटाबेस नाम के — प्रत्येक असाइन की गई सिंक इससे अपना स्वयं का डेटाबेस प्राप्त करती है। हर DSN की तरह इसे स्थानीय रूप से mode-600 में संग्रहीत किया जाता है और कभी Entity Enricher को नहीं भेजा जाता।
ee-database host pair --server https://entityenricher.ai \ --dsn "postgres://user:pass@host:5432/" <token>
पेयरिंग लॉगिन के provisioning अधिकारों (create database, DDL, DML) की स्वयं जाँच करती है और किसी गायब grant पर तुरंत विफल हो जाती है। कम-विशेषाधिकार वाला लॉगिन पसंद है? --admin-dsn जोड़ें और provisioning इसके बजाय एडमिन कनेक्शन के माध्यम से हर गायब role और डेटाबेस बनाता है — एडमिन DSN केवल provision समय पर उपयोग किया जाता है, कभी स्टोर नहीं किया जाता।
ee-database host run
होस्ट एक control-plane WebSocket रखता है और UI में की गई असाइनमेंट पर प्रतिक्रिया करता है: डेटाबेस रजिस्टर करते समय होस्ट चुनें, या बाद में डेटाबेस के Overview टैब पर। प्रत्येक असाइन की गई सिंक को क्लेम किया जाता है, यदि इसका डेटाबेस अनुपलब्ध हो तो बनाया जाता है (सिंक के नाम से snake_case में; होस्ट के config.json में database_names के माध्यम से प्रति सिंक ओवरराइड करें), फिर नीचे दिए गए सामान्य लूप द्वारा सिंक किया जाता है।
पहले से किसी अन्य क्लाइंट के साथ पेयर किया गया डेटाबेस रिपोर्ट किया जाता है और छोड़ दिया जाता है — कभी टेक-ओवर नहीं किया जाता। UI में होस्ट को रिवोक करने से मशीन तुरंत कट जाती है, जिसमें उसके द्वारा दावा किया गया हर per-database क्रेडेंशियल शामिल है; असाइनमेंट और पहले से सिंक किया गया डेटा बना रहता है, इसलिए दोबारा पेयर किया गया होस्ट वहीं से फिर शुरू होता है जहाँ पुराना रुका था।
डेल्टा एक सख्त प्रति-डेटाबेस FIFO आउटबॉक्स के माध्यम से Entity Enricher से बाहर जाते हैं। सर्वर दृश्यमान विंडो को 120 सेकंड के लिए लीज़ करता है और इसे एक बैच के रूप में पुश करता है; क्लाइंट पूरे बैच को एक ट्रांज़ैक्शन में अप्लाई करता है और ack से जवाब देता है, जो कर्सर को आगे बढ़ाता है और अगली विंडो को तुरंत ट्रिगर करता है। बैच के बीच में बंद होने वाला क्लाइंट लीज़ समाप्ति और सर्वर-साइड री-पुश द्वारा कवर होता है — कुछ भी खोता नहीं है या डबल-कमिट नहीं होता।
बूटस्ट्रैप और स्टेडी-स्टेट एक ही कोड पाथ साझा करते हैं। यदि आपका डेटाबेस पहले से सीड किया गया है तो --skip-bootstrap के साथ बूटस्ट्रैप स्किप करें।
प्रत्येक स्टेटमेंट एक _sync_revision रखता है ताकि पुरानी रो कभी नई रो को ओवरराइट न करे, भले ही क्रम से बाहर हो।
SQL एरर पूरे बैच को रोलबैक कर देता है और विफल डेल्टा को उस पूरे दोषी स्टेटमेंट के साथ रिपोर्ट करता है। सर्वर उस एनरिचमेंट के बैच को क्वारंटीन कर देता है और कतार को उसके बिना दोबारा पुश करता है — क्लाइंट बाकी सब लागू करता रहता है। केवल वही विफलता non-zero के साथ बाहर निकलती है जो किसी डेल्टा का नाम नहीं लेती।
हर लागू विंडो प्रति टेबल यह बताती है कि उसने कौन-सा शेप लिखा — इसलिए रात्रिकालीन री-एनरिचमेंट का आकार आँकने के लिए उन डेल्टा पर लॉग-खुदाई कभी नहीं करनी पड़ती जो पहले ही ack होकर जा चुके हैं।
applying 12 delta(s) (10831 .. 10842) in one transaction applied 12 delta(s) in 84ms — 38 statement(s): mushroom 4 upserts, mushroom_common_names 12 upserts + 4 prunes, mushroom_human_uses 14 upserts + 4 prunes acked up to delta 10842
एक upsert यानी एक पंक्ति, इसलिए ये गिनतियाँ पंक्तियों की गिनतियाँ हैं; prune वह एकमात्र revision-guarded DELETE है जो उन child या junction पंक्तियों को साफ़ करता है जिन पर नया payload अब दावा नहीं करता। Child रिकॉर्ड यथास्थान reconcile किए जाते हैं — कभी मिटाकर दोबारा insert नहीं किए जाते। प्रति डेल्टा एक लाइन के लिए --verbose जोड़ें, जिसमें उसका एंटिटी टाइप, वॉल टाइम और अपना शेप शामिल होता है।
टारगेट डायलेक्ट Entity Enricher में स्कीमा-डेटाबेस रजिस्ट्रेशन से तय होता है — क्लाइंट वही SQL लागू करता है जो सर्वर रेंडर करता है। लॉन्च डायलेक्ट PostgreSQL है; MySQL / MariaDB, SQL Server और Oracle रेंडरर प्रस्तावित हैं (MySQL ड्राइवर पहले से बंडल है)। मल्टी-स्टेटमेंट एप्लिकेशन हर ड्राइवर के अनुसार संभाला जाता है (pgx simple protocol, MySQL multiStatements)।
यदि लक्ष्य डेटाबेस पहले से मौजूद है, तो लॉगिन को केवल डेटाबेस पर CONNECT और लक्ष्य स्कीमा पर USAGE + CREATE चाहिए। (PostgreSQL 15 से, public डिफ़ॉल्ट रूप से सभी को CREATE नहीं देता।)
बाकी सब कुछ ओनरशिप से निकलता है: क्लाइंट रेप्लिका टेबल्स खुद बनाता है, इसलिए वही उनका ओनर होता है, और ओनरशिप से वे रीड और राइट अधिकार अपने आप मिल जाते हैं जिनकी डेटा डेल्टा को ज़रूरत होती है। ओनरशिप वैकल्पिक नहीं है — फ़ीड माइग्रेशन स्टेटमेंट्स भी भेजती है (ALTER TABLE …, CREATE INDEX …) जिन्हें PostgreSQL सिर्फ़ टेबल ओनर तक सीमित रखता है, और ग्रांट्स का कोई भी संयोजन इसका विकल्प नहीं है।
अगर रेप्लिका टेबलें पहले से किसी दूसरे ओनर के अधीन मौजूद हैं, तो रन की राइट्स प्रीफ़्लाइट फिर भी पास हो जाती है — लॉगिन नई टेबलें बना सकता है — लेकिन पहला माइग्रेशन डेल्टा फ़ेल हो जाता है। ग्रांट्स जोड़ने के बजाय उन्हें ALTER TABLE … OWNER TO <login> से ट्रांसफ़र करें (या लॉगिन को ओनर रोल की मेंबरशिप दें)।
आपका डेटाबेस जिस स्टेटमेंट को अस्वीकार करता है — आमतौर पर इसकी वजह किसी नए यूनिक इंडेक्स के तहत पहले से मौजूद डुप्लिकेट होती है — वह फ़ीड को नहीं रोकता। बैच रोलबैक हो जाता है, क्लाइंट विफल डेल्टा को पूरे दोषी स्टेटमेंट के साथ रिपोर्ट करता है (कभी काट-छाँट किए बिना), और सर्वर उस एनरिचमेंट के बैच को क्वारंटीन करके कतार को उसके बिना दोबारा पुश कर देता है। आपका क्लाइंट उसके बाद की हर चीज़ लागू करता रहता है।
क्वारंटीन किया गया काम Database Sync पेज के Quarantine टैब में तब तक सूचीबद्ध रहता है जब तक आप उसे नहीं निपटाते: अपने डेटाबेस में कारण ठीक करें और reinject करें — जो पुराने स्टेटमेंट को दोबारा चलाने के बजाय एंटिटी को उसकी मौजूदा स्थिति से फिर से प्रोजेक्ट करता है — या यदि वह रो अब मायने नहीं रखती तो उसे हटा दें।
विफल bootstrap की बात अलग है: स्नैपशॉट एक ही ट्रांज़ैक्शन होता है, इसलिए कुछ भी आंशिक रूप से लागू नहीं होता, और क्लाइंट उसे पेयरिंग की प्रोफ़ाइल डायरेक्टरी में snapshot-failed.sql के रूप में सहेज देता है (मोड 0600, हर प्रयास पर बदला जाता है, अगली सफलता पर हटा दिया जाता है) ताकि आप उसे psql -f से जाँच या दोबारा चला सकें।
क्लाइंट :443/wss पर WebSocket शुरू करता है। आपका डेटाबेस होस्ट कभी भी इनबाउंड कनेक्शन स्वीकार नहीं करता — कोई पोर्ट खोलने की ज़रूरत नहीं, कोई इनग्रेस कॉन्फ़िगर करने की ज़रूरत नहीं।
एक क्रेडेंशियल एक ही database sync से बंधा होता है। दोबारा पेयर करने पर यह रोटेट हो जाता है और पिछला लाइव कनेक्शन तुरंत हटा देता है।
365-दिन का रिफ्रेश टोकन (mode-600 में संग्रहीत) 15-मिनट के एक्सेस टोकन के लिए एक्सचेंज किया जाता है जो WebSocket को प्रमाणित करते हैं। UI में रद्द करने से एक लाइव क्लाइंट ~1 सेकंड के भीतर डिस्कनेक्ट हो जाता है।
मैनेज्ड होस्ट JWT के बजाय एक छोटी eeh_… की से पेयर होता है: सर्वर केवल उसका हैश रखता है, वह कभी एक्सपायर नहीं होती, और उसे खत्म करने का तरीका है UI में होस्ट को रद्द करना।
प्रति-प्रोफ़ाइल लॉक दो प्रोसेस को एक ही पेयरिंग एक साथ चलाने से रोकता है — वरना वे लगातार एक-दूसरे का WebSocket सेशन हटाते रहेंगे।
क्लाइंट को सिंक किए गए स्कीमा तक सीमित एक समर्पित रोल के रूप में चलाएँ, ताकि लीक हुआ टोकन और कुछ न छू सके — लेकिन उसी रोल को रेप्लिका टेबल बनाने दें ताकि वह उनका मालिक बने। माइग्रेशन स्टेटमेंट को ग्रांट नहीं, ओनरशिप चाहिए।
| कमांड | यह क्या करता है |
|---|---|
| ee-database pair --server URL | ब्राउज़र-कन्फर्म्ड डिवाइस-कोड पेयरिंग। चुनें कि कौन सा डेटाबेस सिंक करना है। |
| ee-database pair --server URL <token> | Database Sync पेज पर जारी किए गए टोकन से पेयर करें (हेडलेस-अनुकूल)। |
| ee-database run --dsn DSN [--save-dsn] [--skip-bootstrap] | स्नैपशॉट से बूटस्ट्रैप करें (जब तक स्किप न किया जाए), फिर कनेक्ट करें और डेल्टा अप्लाई करें। |
| ee-database run … --create-missing | यदि टारगेट डेटाबेस मौजूद न हो तो पहले उसे DSN के अपने क्रेडेंशियल्स से बनाएं (postgres के लिए CREATEDB और mysql के लिए CREATE प्रिविलेज आवश्यक है)। |
| ee-database run … --create-missing --admin-dsn DSN | target DSN जिन सब चीज़ों का नाम देता है, उन्हें एक admin connection के ज़रिए bootstrap करें: गायब role/user (DSN के password के साथ) और उसके स्वामित्व वाला database। इसके बाद target DSN को किसी create rights की ज़रूरत नहीं होती; admin DSN कभी store नहीं किया जाता। |
| ee-database run --all | एक ही process से हर paired database को एक साथ sync करें (प्रत्येक को एक saved DSN चाहिए)। |
| ee-database run … --verbose | सिर्फ़ प्रति-विंडो सारांश नहीं, बल्कि हर डेल्टा का राइट शेप और वॉल टाइम लॉग करें। host run द्वारा भी स्वीकार किया जाता है। |
| ee-database host pair --server URL --dsn BASE_DSN [--admin-dsn DSN] <token> | इस मशीन को प्रबंधित सिंक होस्ट के रूप में एक बार पेयर करें — बेस DSN आपके डेटाबेस सर्वर का नाम देता है (डेटाबेस का नाम नहीं) और कभी मशीन से बाहर नहीं जाता; टोकन Sync hosts डायलॉग से मिलता है (Database Sync पेज पर Sync hosts टूलबार बटन)। प्रति सर्वर एक पेयरिंग: आप कई Entity Enricher सर्वरों के साथ साथ-साथ पेयर कर सकते हैं। |
| ee-database host run [--server URL] | मैनेज्ड मोड: इस होस्ट को असाइन किया गया हर database sync क्लेम कर लिया जाता है, मौजूद न होने पर बना दिया जाता है और स्वतः सिंक में रखा जाता है — कोई प्रति-डेटाबेस पेयरिंग नहीं, और एक ही बार में हर पेयर्ड सर्वर पर लागू (--server इसे एक तक सीमित कर देता है)। किसी अन्य क्लाइंट के साथ पहले से पेयर्ड डेटाबेस की सूचना दी जाती है, उसे कभी टेक ओवर नहीं किया जाता। |
| ee-database host status / host disconnect [--server URL] | इस मशीन की होस्ट पेयरिंग दिखाएँ या हटाएँ। सर्वर-साइड रिवोक Sync hosts कार्ड से करें। |
| ee-database status | pairing स्थिति, server URL और paired databases दिखाएँ। |
| ee-database disconnect | किसी एक pairing के local credentials भूल जाएँ। UI से server-side पर revoke करें। |
| ee-database version | प्रिंट संस्करण। |
क्रेडेंशियल mode-600 में सेव होते हैं, हर पेयर किए गए डेटाबेस के लिए एक प्रोफ़ाइल, ~/.config/ee-database/profiles/ के अंदर — हर डेटाबेस को एक बार पेयर करें, और जब कई पेयर हों तो --database NAME उनमें से एक चुनता है। बिल्कुल भी ऑटोमेशन नहीं चाहिए? वही फ़ीड सादे REST के रूप में भी उपलब्ध है: GET /api/databases//changes फिर POST /api/databases//ack — देखें Database Sync।
क्लाइंट MIT-लाइसेंस्ड है और एक सार्वजनिक रिपॉज़िटरी में रहता है ताकि कोई भी ठीक-ठीक ऑडिट कर सके कि उनके डेटाबेस के विरुद्ध क्या चलता है।
Source: github.com/TOT-Concept/ee-database
रिलीज़: github.com/TOT-Concept/ee-database/releases — प्रत्येक बाइनरी प्रकाशन से पहले cosign से साइन की जाती है।
इंस्टॉलर का ऑडिट करें: curl -fsSL https://entityenricher.ai/install-eedatabase.sh | less