Model References
datagen allows you to create relationships between different models, enabling you to generate realistic, interconnected data. The self.datagen object is used to reference fields from other models, while self references fields from the same model.
Reference Syntax
Section titled “Reference Syntax”Same-Model References
Section titled “Same-Model References”self.field_name(iter)Cross-Model References
Section titled “Cross-Model References”self.datagen.ModelName().field_name(iter)Key Concepts
Section titled “Key Concepts”On-Demand Generation
Section titled “On-Demand Generation”If you request an index beyond already-generated rows, datagen automatically generates rows up to that index, then returns the requested value.
Example:
// User model has metadata count: 5 (generates only 5 rows initially)// But in Project model, we access User.id(10)
func owner_id() {  return self.datagen.User().id(10)  // Datagen will generate User rows for iter 5-10 first, then return id(10)}Separation of Concerns
Section titled “Separation of Concerns”datagen separates three distinct responsibilities:
- Generation logic - Defined in 
gensfunctions (how to create values) - Parameter values - Provided in 
callssection (configuration for parameterized fields) - Field access - Done via 
selforself.datagen(retrieving generated values) 
Example:
model Product {  fields {    id() int    price(min float64, max float64) float64  // Parameterized field    discounted_price() float64  }
  gens {    func id() {      return iter + 1    }
    // Generation logic: how to create a price    func price(min float64, max float64) {      return FloatBetween(min, max)    }
    func discounted_price() {      // Access: retrieve the generated price value      return self.price(iter) * 0.9    }  }
  // Parameter values: configure the price range  calls {    price(10.0, 100.0)  }}In this example:
- Generation logic (
FloatBetween) is in thepricefunction - Parameter values (10.0, 100.0) are in the 
callssection - Field access (
self.price(iter)) retrieves the generated value 
Same-Model References
Section titled “Same-Model References”Reference other fields within the same model to create calculated or dependent fields.
Example: Calculated Fields
Section titled “Example: Calculated Fields”model Order {  fields {    id() int    base_amount() float64    tax_amount() float64    total_amount() float64  }
  gens {    func id() {      return iter + 1    }
    func base_amount() {      return FloatBetween(50.0, 500.0)    }
    func tax_amount() {      return self.base_amount(iter) * 0.08    }
    func total_amount() {      return self.base_amount(iter) + self.tax_amount(iter)    }  }}Running the example:
datagenc gen Order.dg -n 5Output:
Order{id:1 base_amount:152.76 tax_amount:12.220799999999999 total_amount:164.9808}Order{id:2 base_amount:477.97 tax_amount:38.2376 total_amount:516.2076000000001}Order{id:3 base_amount:350.43 tax_amount:28.0344 total_amount:378.4644}Order{id:4 base_amount:80.09 tax_amount:6.4072000000000005 total_amount:86.4972}Order{id:5 base_amount:170.45 tax_amount:13.636 total_amount:184.08599999999998}Cross-Model References
Section titled “Cross-Model References”Create relationships between different models to generate interconnected, realistic data.
Simple Cross-Model Example
Section titled “Simple Cross-Model Example”Create two models in a directory library:
model Author {  fields {    id() int    name() string    country() string  }
  gens {    func id() {      return iter + 1    }
    func name() {      return Name()    }
    func country() {      countries := []string{"USA", "UK", "Canada", "Australia", "India"}      return countries[IntBetween(0, len(countries)-1)]    }  }}model Book {  fields {    id() int    title() string    author_id() int    author_name() string  }
  gens {    func id() {      return iter + 1    }
    func title() {      return fmt.Sprintf("Book Title %d", iter+1)    }
    func author_id() {      // Reference Author model's id field      return self.datagen.Author().id(IntBetween(0, 4))    }
    func author_name() {      // Reference Author model's name field      authorIdx := self.author_id(iter) - 1      return self.datagen.Author().name(authorIdx)    }  }}Running the example:
datagenc gen ./library -n 5Output:
Author{id:1 name:Lillian Haley country:USA}Author{id:2 name:Emilie Torphy country:Canada}Author{id:3 name:Verner Nicolas country:India}Author{id:4 name:Macie Schowalter country:UK}Author{id:5 name:Americo Konopelski country:Australia}Book{id:1 title:Book Title 1 author_id:2 author_name:Emilie Torphy}Book{id:2 title:Book Title 2 author_id:4 author_name:Macie Schowalter}Book{id:3 title:Book Title 3 author_id:1 author_name:Lillian Haley}Book{id:4 title:Book Title 4 author_id:3 author_name:Verner Nicolas}Book{id:5 title:Book Title 5 author_id:2 author_name:Emilie Torphy}Advanced Multi-Model Example
Section titled “Advanced Multi-Model Example”Create complex relationships with conditional logic:
model Customer {  metadata {    count: 1000  }
  fields {    id() int    tier() string  }
  gens {    func id() {      return iter + 1    }
    func tier() {      rand := IntBetween(1, 100)      if rand <= 10 {        return "premium"      } else if rand <= 40 {        return "gold"      }      return "standard"    }  }}model Order {  fields {    id() int    customer_id() int    discount() float32    total() float32  }
  gens {    func id() {      return iter + 1    }
    func customer_id() {      return self.datagen.Customer().id(IntBetween(0, 999))    }
    func discount() {      // Get customer tier and apply discount      tier := self.datagen.Customer().tier(iter)      if tier == "premium" {        return 20.0      } else if tier == "gold" {        return 10.0      }      return 2.0    }
    func total() {      base := Float32Between(100.0, 500.0)      discount := self.discount(iter)      return base * (1.0 - discount/100.0)    }  }}Running the example:
datagenc gen ./orders -n 5Output:
Customer{id:1 tier:standard}Customer{id:2 tier:standard}Customer{id:3 tier:standard}Customer{id:4 tier:standard}Customer{id:5 tier:premium}Order{id:1 customer_id:444 discount:2 total:288.7864}Order{id:2 customer_id:519 discount:2 total:397.6546}Order{id:3 customer_id:519 discount:2 total:378.1134}Order{id:4 customer_id:563 discount:2 total:337.071}Order{id:5 customer_id:693 discount:20 total:265.168}Common Patterns
Section titled “Common Patterns”Foreign Key Relationships
Section titled “Foreign Key Relationships”// In Order modelfunc user_id() {  maxUsers := 1000  return self.datagen.User().id(IntBetween(0, maxUsers-1))}Cascading References
Section titled “Cascading References”// In Payment modelfunc order_id() {  return self.datagen.Order().id(iter)}
func customer_id() {  // Get customer_id from the referenced Order  return self.datagen.Order().customer_id(iter)}Cyclic Data with Modulo
Section titled “Cyclic Data with Modulo”func assigned_user() {  totalUsers := 50  return self.datagen.User().id(iter % totalUsers)}Conditional References
Section titled “Conditional References”func manager_id() {  if iter < 10 {    return 1  // First 10 records report to manager 1  }  return self.datagen.User().id(IntBetween(0, 9))}Key Benefits
Section titled “Key Benefits”- Data Consistency - Ensures referenced IDs actually exist
 - Realistic Relationships - Creates proper foreign key relationships
 - Dynamic References - Can reference any field from any model
 - Flexible Logic - Combine multiple model references in complex ways
 
See Also
Section titled “See Also”- Examples - Reference - Practical reference examples
 - Data Model - Core model concepts
 - iter Variable - Using iter with references