1. ent का परिचय

Ent एक एंटिटी फ्रेमवर्क है जो फेसबुक ने गो भाषा के लिए विशेष रूप से विकसित किया है। यह बड़े पैमाने पर डेटा मॉडल ऍप्लीकेशन बनाने और बनाए रखने की प्रक्रिया को सरल बनाता है। Ent फ्रेमवर्क मुख्य रूप से निम्नलिखित सिद्धांतों का पालन करता है:

  • डेटाबेस स्कीमा को ग्राफ संरचना के रूप में आसानी से मॉडल करें।
  • गो भाषा कोड के रूप में स्कीमा को परिभाषित करें।
  • कोड जेनरेशन पर आधारित स्थाई प्रकार को लागू करें।
  • डेटाबेस क्वेरी और ग्राफ ट्रावर्सल लिखना बहुत सरल है।
  • गो टेम्प्लेट का उपयोग करके आसानी से विस्तारित और समायोजित करें।

2. पर्यावरण सेटअप

Ent फ्रेमवर्क का उपयोग शुरू करने के लिए सुनिश्चित करें कि आपके डेवलपमेंट पर्यावरण में गो भाषा स्थापित है।

यदि आपका प्रोजेक्ट डायरेक्टरी GOPATH के बाहर है, या यदि आप GOPATH के बारे में नहीं जानते हैं, तो आप निम्नलिखित कमांड का उपयोग करके एक नया गो मॉड्यूल प्रोजेक्ट बनाने के लिए उपयोग कर सकते हैं:

go mod init entdemo

इससे आपके entdemo प्रोजेक्ट के लिए एक नया गो मॉड्यूल की शुरुआत करेगा और एक नया go.mod फ़ाइल बनाएगा।

3. पहले स्कीमा को परिभाषित करना

3.1. ent CLI का उपयोग करके स्कीमा बनाना

सबसे पहले, आपको अपने प्रोजेक्ट के रूट डायरेक्टरी में निम्नलिखित कमांड को चलाना होगा ताकि ent CLI टूल का उपयोग करके 'User' नामक स्कीमा बनाया जा सके:

go run -mod=mod entgo.io/ent/cmd/ent new User

उपरोक्त कमांड से entdemo/ent/schema/ डायरेक्टरी में 'User' स्कीमा बनाएगा:

फ़ाइल entdemo/ent/schema/user.go:

package schema

import "entgo.io/ent"

// User हमारे प्रयोक्ता एन्टिटी के लिए स्कीमा परिभाषण करता है।
type User struct {
    ent.Schema
}

// User के फ़ील्ड्स।
func (User) Fields() []ent.Field {
    return nil
}

// User के एजेस।
func (User) Edges() []ent.Edge {
    return nil
}

3.2. फ़ील्ड जोड़ना

अगले, हमें यूज़र स्कीमा में फ़ील्ड परिभाषाएँ जोड़नी होगी। यहां यूज़र मॉडल के लिए दो फ़ील्ड जोड़ने का एक उदाहरण है।

फ़ाइल बदली गई entdemo/ent/schema/user.go:

package schema

import (
    "entgo.io/ent"
    "entgo.io/ent/schema/field"
)

// User के फ़ील्ड्स।
func (User) Fields() []ent.Field {
    return []ent.Field{
        field.Int("age").
            Positive(),
        field.String("name").
            Default("अज्ञात"),
    }
}

यह कोड यूज़र मॉडल के लिए दो फ़ील्ड्स की परिभाषा करता है: उम्र और नाम, जहां उम्र एक सकारात्मक पूर्णांक है और 'नाम' एक डिफ़ॉल्ट मान "अज्ञात" के साथ एक स्ट्रिंग है।

3.3. डेटाबेस एंटिटी जनरेट करना

स्कीमा को परिभाषित करने के बाद, आपको go generate कमांड को चलाना होगा ताकि निम्नलिखित डेटाबेस ऍक्सेस लॉजिक जनरेट किया जा सके।

अपने प्रोजेक्ट के रूट डायरेक्टरी में निम्नलिखित कमांड को चलाएं:

go generate ./ent

यह कमांड पूर्व में परिभाषित स्कीमा के आधार पर संबंधित गो कोड उत्पन्न करेगा, जिससे निम्नलिखित फ़ाइल संरचना होगी:

4.1. डेटाबेस कनेक्शन को आरंभ करना

MySQL डेटाबेस के साथ एक कनेक्शन स्थापित करने के लिए, हम ent framework द्वारा प्रदान की गई Open फ़ंक्शन का उपयोग कर सकते हैं। पहले, MySQL ड्राइवर को आयात करें और फिर सही कनेक्शन स्ट्रिंग प्रदान करें ताकि डेटाबेस कनेक्शन को आरंभ किया जा सके।

package main

import (
    "context"
    "log"

    "entdemo/ent"
    
    _ "github.com/go-sql-driver/mysql" // MySQL ड्राइवर को आयात करें
)

func main() {
    // MySQL डेटाबेस के साथ कनेक्शन स्थापित करने के लिए ent.Open का उपयोग करें।
    // नीचे दिए गए प्लेसहोल्डर "your_username", "your_password", और "your_database" को बदलना न भूलें।
    client, err := ent.Open("mysql", "your_username:your_password@tcp(localhost:3306)/your_database?parseTime=True")
    if err != nil {
        log.Fatalf("mysql कनेक्शन खोलने में विफल: %v", err)
    }
    defer client.Close()

    // स्वचालित माइग्रेशन उपकरण 
    ctx := context.Background()
    if err := client.Schema.Create(ctx); err != nil {
        log.Fatalf("स्कीमा संसाधन बनाने में विफल: %v", err)
    }
    
    // यहां अतिरिक्त व्यावसायिक तर्क लिखा जा सकता है
}

4.2. संविदा बनाना

एक उपयोगकर्ता संविदा बनाने में एक नया संविदा ऑब्जेक्ट बनाना और इसे Save या SaveX विधि का उपयोग करके डेटाबेस में संग्रहीत करना शामिल है। निम्नलिखित कोड प्रदर्शित करता है कि कैसे एक नया उपयोगकर्ता संविदा बनाने और age और name नामक दो क्षेत्रों को प्रारंभिक करना।

// CreateUser फ़ंक्शन का उपयोग नए उपयोगकर्ता संविदा बनाने के लिए किया जाता है
func CreateUser(ctx context.Context, client *ent.Client) (*ent.User, error) {
    // client.User.Create() का उपयोग करके उपयोगकर्ता निर्माण के लिए अनुरोध बनाने के लिए,
    // तो उसके बाद SetAge और SetName विधियों को चेन करें ताकि संविदा क्षेत्रों के मान सेट किए जा सकें।
    u, err := client.User.
        Create().
        SetAge(30).    // उपयोगकर्ता की उम्र सेट करें
        SetName("a8m"). // उपयोगकर्ता का नाम सेट करें
        Save(ctx)     // संविदा को डेटाबेस में सहेजने के लिए Save को कॉल करें
    if err != nil {
        return nil, fmt.Errorf("उपयोगकर्ता बनाने में विफल: %w", err)
    }
    log.Println("उपयोगकर्ता बनाया गया: ", u)
    return u, nil
}

main फ़ंक्शन में, आप CreateUser फ़ंक्शन को कॉल करके एक नया उपयोगकर्ता संविदा बनाने के लिए कॉल कर सकते हैं।

func main() {
    // ...डेटाबेस कनेक्शन स्थापित करने के लिए छोड़ दिया गया कोड

    // एक उपयोगकर्ता संविदा बनाएं
    u, err := CreateUser(ctx, client)
    if err != nil {
        log.Fatalf("उपयोगकर्ता बनाने में विफल: %v", err)
    }
    log.Printf("उपयोगकर्ता बनाया गया: %#v\n", u)
}

4.3. संविदा क्वेरी करना

संविदा क्वेरी करने के लिए, हम ent द्वारा जनरेट किए गए क्वेरी बिल्डर का उपयोग कर सकते हैं। निम्नलिखित कोड प्रदर्शित करता है कि "a8m" नाम के एक उपयोगकर्ता को कैसे क्वेरी किया जाता है।

// QueryUser फ़ंक्शन का उपयोग निर्दिष्ट नाम के उपयोगकर्ता संविदा क्वेरी करने के लिए किया जाता है
func QueryUser(ctx context.Context, client *ent.Client) (*ent.User, error) {
    // client.User.Query() का उपयोग करके उपयोगकर्ता के लिए क्वेरी बनाने के लिए,
    // तो उसके बाद Where विधि को चेन करें ताकि क्वेरी की शर्तें जोड़ सकें, जैसे कि उपयोगकर्ता नाम से क्वेरी करना
    u, err := client.User.
        Query().
        Where(user.NameEQ("a8m")).      // क्वेरी शर्त जोड़ें, इस मामले में, नाम "a8m" है
        Only(ctx)                      // Only विधि इस इंडिकेट करती है कि केवल एक परिणाम की उम्मीद है
    if err != nil {
        return nil, fmt.Errorf("उपयोगकर्ता क्वेरी करने में विफल: %w", err)
    }
    log.Println("उपयोगकर्ता लौटाया गया है: ", u)
    return u, nil
}

main फ़ंक्शन में, आप QueryUser फ़ंक्शन को कॉल करके उपयोगकर्ता संविदा क्वेरी कर सकते हैं।

func main() {
    // ...डेटाबेस कनेक्शन स्थापित करने और उपयोगकर्ता बनाने के लिए छोड़ दिया गया कोड

    // उपयोगकर्ता संविदा क्वेरी करें
    u, err := QueryUser(ctx, client)
    if err != nil {
        log.Fatalf("उपयोगकर्ता क्वेरी करने में विफल: %v", err)
    }
    log.Printf("क्वेरी किए गए उपयोगकर्ता: %#v\n", u)
}

5.1. किनारों और उलटी किनारों को समझना

ent framework में, डेटा मॉडल को ग्राफ संरचना के रूप में दृश्यीकृत किया जाता है, जहां प्रकार ग्राफ में नोड के रूप में प्रतिष्ठान होते हैं, और प्रकार के बीच संबंध क

6.2. ग्राफ संरचना का अवलोकन

ent में ग्राफ ट्रावर्सल कोड लिखना मुख्य रूप से संबंधों के बीच किनारों के माध्यम से डेटा का प्रश्न करने और जोड़ने को शामिल करता है। नीचे एक सरल उदाहरण दिया गया है जो दिखाता है कि ent में ग्राफ संरचना को कैसे अवलोकन किया जा सकता है:

import (
    "context"
    "log"

    "entdemo/ent"
)

// GraphTraversal ग्राफ संरचना को अवलोकन करने का एक उदाहरण है
func GraphTraversal(ctx context.Context, client *ent.Client) error {
    // "ऐरियल" नाम के उपयोगकर्ता का प्रश्न करें
    a8m, err := client.User.Query().Where(user.NameEQ("ऐरियल")).Only(ctx)
    if err != nil {
        log.Fatalf("उपयोगकर्ता का प्रश्न करने में विफल: %v", err)
        return err
    }

    // ऐरियल के सभी कारों का अवलोकन करें
    cars, err := a8m.QueryCars().All(ctx)
    if err != nil {
        log.Fatalf("कारों का प्रश्न करने में विफल: %v", err)
        return err
    }
    for _, car := range cars {
        log.Printf("ऐरियल के पास एक कार है जिसका मॉडल है: %s", car.Model)
    }

    // वह सभी समूहों का अवलोकन करें जिसमें ऐरियल सदस्य है
    groups, err := a8m.QueryGroups().All(ctx)
    if err != nil {
        log.Fatalf("समूहों का प्रश्न करने में विफल: %v", err)
        return err
    }
    for _, g := range groups {
        log.Printf("ऐरियल समूह का सदस्य है: %s", g.Name)
    }

    return nil
}

ऊपर का कोड ग्राफ ट्रावर्सल का एक मौलिक उदाहरण है, जो पहले एक उपयोगकर्ता का प्रश्न करता है और फिर उपयोगकर्ता की कारों और समूहों का अवलोकन करता है।

7. डेटाबेस स्कीमा का दृश्यीकरण

7.1. एटलस टूल का इंस्टॉल करना

ent द्वारा जनरेट किया गया डेटाबेस स्कीमा को विज़ुअलाइज़ करने के लिए हम Atlas टूल का उपयोग कर सकते हैं। Atlas की स्थापना की चरणों में सरलता है। उदाहरण के रूप में, macOS पर, आप इसे brew का उपयोग करके स्थापित कर सकते हैं:

brew install ariga/tap/atlas

नोट: Atlas एक सार्वभौमिक डेटाबेस माइग्रेशन टूल है जो विभिन्न डेटाबेस के लिए तालिका संरचना संस्करण प्रबंधन कर सकता है। Atlas का विस्तृत परिचय बाद के अध्यायों में दिया जायेगा।

7.2. ERD और SQL स्कीमा जेनरेट करना

Atlas का उपयोग स्कीमा को देखने और निर्यात करने के लिए बहुत सरल है। एटलस को इंस्टॉल करने के बाद, आप निम्नलिखित कमांड का उपयोग करके Entity-Relationship Diagram (ERD) को देख सकते हैं:

atlas schema inspect -d [डेटाबेस_dsn] --format dot

या सीधे SQL स्कीमा उत्पन्न कर सकते हैं:

atlas schema inspect -d [डेटाबेस_dsn] --format sql

जहां [डेटाबेस_dsn] आपके डेटाबेस के डेटा स्रोत नाम (DSN) को संदर्भित करता है। उदाहरण के लिए, एक SQLite डेटाबेस के लिए, यह शायद हो सकता है:

atlas schema inspect -d "sqlite://file:ent.db?mode=memory&cache=shared" --format dot

इन कमांड्स द्वारा उत्पन्न की गई आउटपुट को आगे के संबंधित उपकरणों का उपयोग करके दृश्यों या दस्तावेज़ के रूप में और भी सुधारा जा सकता है।

8. स्कीमा माइग्रेशन

8.1. स्वचालित माइग्रेशन और संस्करणित माइग्रेशन

ent दो स्कीमा माइग्रेशन रणनीतियों का समर्थन करता है: स्वचालित माइग्रेशन और संस्करणित माइग्रेशन। स्वचालित माइग्रेशन अंतरंग परीक्षण और स्वचालित माइग्रेशन की जरूरत है जो विकास और परीक्षण के लिए उपयुक्त है। संस्करणित माइग्रेशन में माइग्रेशन स्क्रिप्ट जेनरेट करने और उन्हें उत्पन्न करने की प्रक्रिया शामिल होती है और इससे पहले इसे ध्यानपूर्वक समीक्षा और परीक्षण की जरूरत होती है।

सुझाव: स्वचालित माइग्रेशन के लिए, अनुभाग 4.1 में दी गई सामग्री का संदर्भ दें।

8.2. संस्करणित माइग्रेशन का क्रियान्वन

संस्करणित माइग्रेशन की प्रक्रिया माइग्रेशन फ़ाइलें उत्पन्न करने से जुड़ी होती है। निम्नलिखित कमांड्स हैं:

माइग्रेशन फ़ाइलें उत्पन्न करने के लिए:

atlas migrate diff -d ent/schema/path --dir migrations/dir

इसके बाद, इन माइग्रेशन फ़ाइलें डेटाबेस पर लागू की जा सकती हैं:

atlas migrate apply -d migrations/dir --url database_dsn

इस प्रक्रिया के बाद, आप माइग्रेशन का इतिहास संग्रहीत कर सकते हैं और हर माइग्रेशन से पहले व्यापक समीक्षा सुनिश्चित कर सकते हैं।

सुझाव: https://github.com/ent/ent/tree/master/examples/start पर उदाहरण को संदर्भित करें।