Go और PostgreSQL एक आदर्श जोड़ी क्यों हैं?
\n\nबैकएंड डेवलपमेंट की दुनिया में Go (या Golang) और PostgreSQL ने उच्च-लोड और विश्वसनीय सिस्टम बनाने के लिए एक शक्तिशाली जोड़ी के रूप में अपनी पहचान बनाई है। Go हमें अविश्वसनीय प्रदर्शन, सरलता और उत्कृष्ट समवर्ती समर्थन प्रदान करता है, जबकि PostgreSQL समृद्ध कार्यक्षमता, विश्वसनीयता और विस्तारशीलता वाला एक औद्योगिक डेटाबेस है। इन दोनों को मिलाकर, आपको एक ऐसा स्टैक मिलता है जो स्टार्टअप के लोड और एंटरप्राइज प्रोजेक्ट की आवश्यकताओं को संभालने में सक्षम है।
\n\nइस लेख में, हम केवल सिंटैक्स पर सरसरी नज़र नहीं डालेंगे। हम एक पूर्ण व्यावहारिक गाइड बनाएंगे: ड्राइवर इंस्टॉल करने से लेकर कनेक्शन पूल को ऑप्टिमाइज़ करने और ट्रांजेक्शन के साथ काम करने तक। आप सीखेंगे कि सामान्य गलतियों से कैसे बचें और PostgreSQL के साथ काम करने के लिए Go में कुशल कोड कैसे लिखें। चलिए शुरू करते हैं!
\n\nशुरुआत: ड्राइवर चुनना और कनेक्ट करना
\n\nसबसे पहले हमें ड्राइवर इंस्टॉल करना होगा। Go की दुनिया में दो मुख्य उम्मीदवार हैं:
\n- \n
- lib/pq — क्लासिक, सरल, लेकिन अब सक्रिय रूप से समर्थित नहीं है। \n
- pgx — आधुनिक, तेज़, सक्रिय रूप से विकसित, PostgreSQL की अधिक सुविधाओं का समर्थन करता है (जैसे COPY, LISTEN/NOTIFY, arrays)। मैं इसकी अनुशंसा करता हूं। \n
pgx इंस्टॉल करें:
\ngo get github.com/jackc/pgx/v5\n\nअब डेटाबेस से कनेक्ट करने के लिए कोड लिखते हैं। एक फ़ाइल main.go बनाएं:
package main\n\nimport (\n "context"\n "fmt"\n "log"\n\n "github.com/jackc/pgx/v5/pgxpool"\n)\n\nfunc main() {\n // कनेक्शन URL: उपयोगकर्ता, पासवर्ड, होस्ट, पोर्ट, DB नाम\n dsn := "postgres://myuser:mypassword@localhost:5432/mydb?sslmode=disable"\n\n // कनेक्शन पूल बनाएं\n pool, err := pgxpool.New(context.Background(), dsn)\n if err != nil {\n log.Fatalf("पूल बनाने में विफल: %v", err)\n }\n defer pool.Close()\n\n // कनेक्शन की जांच करें\n err = pool.Ping(context.Background())\n if err != nil {\n log.Fatalf("कनेक्ट करने में विफल: %v", err)\n }\n\n fmt.Println("PostgreSQL से सफलतापूर्वक कनेक्ट हुए!")\n}\n\nध्यान दें: हम साधारण कनेक्शन के बजाय pgxpool का उपयोग कर रहे हैं। कनेक्शन पूल प्रोडक्शन के लिए अनिवार्य है। यह कनेक्शन को पुन: उपयोग करने की अनुमति देता है, जिससे उन्हें बनाने और बंद करने के ओवरहेड से बचा जा सकता है।
CRUD ऑपरेशन: बनाना, पढ़ना, अपडेट करना और हटाना
\n\nअब users टेबल के साथ क्लासिक ऑपरेशन लागू करते हैं। मान लें कि हमारे पास एक स्ट्रक्चर है:
type User struct {\n ID int\n Name string\n Age int\n}\n\n\nटेबल बनाना (Create)
\nमाइग्रेशन को अलग टूल से करना बेहतर है, लेकिन उदाहरण के लिए मैं raw SQL दिखाऊंगा:
\nfunc createTable(ctx context.Context, pool *pgxpool.Pool) error {\n query := `\n CREATE TABLE IF NOT EXISTS users (\n id SERIAL PRIMARY KEY,\n name TEXT NOT NULL,\n age INT NOT NULL\n );\n `\n _, err := pool.Exec(ctx, query)\n return err\n}\n\n\nरिकॉर्ड जोड़ना (Insert)
\nजनरेटेड ID वापस पाने के लिए QueryRow का उपयोग करें:
func createUser(ctx context.Context, pool *pgxpool.Pool, user *User) error {\n query := `INSERT INTO users (name, age) VALUES ($1, $2) RETURNING id`\n err := pool.QueryRow(ctx, query, user.Name, user.Age).Scan(&user.ID)\n return err\n}\n\n\nरिकॉर्ड पढ़ना (Select)
\nfunc getUserByID(ctx context.Context, pool *pgxpool.Pool, id int) (*User, error) {\n query := `SELECT id, name, age FROM users WHERE id = $1`\n user := &User{}\n err := pool.QueryRow(ctx, query, id).Scan(&user.ID, &user.Name, &user.Age)\n if err != nil {\n return nil, err\n }\n return user, nil\n}\n\n\n