Skip to content

jdhenke/entds

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

63 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

entds

An Ent extension for batch-creating interconnected entities in a single transaction.

The Problem

When batch-inserting entities that reference each other, you're forced to manually order your inserts to satisfy foreign key constraints, issue individual queries to get IDs back, and then wire everything together. This quickly becomes tedious as your schema grows.

How entds Solves It

entds generates a DataStorer and Future types for your Ent schema. You declare all the entities you want to create, wire up relationships between them (even though nothing has been persisted yet), and call Save. entds handles the rest:

  1. Topological ordering -- entities are inserted in dependency order derived from your schema's required edges.
  2. Bulk operations -- inserts and edge updates are batched for efficiency.
  3. Cycle detection -- cyclic required-edge dependencies are caught at code generation time, not at runtime.

Usage

Add entds as an Ent extension in your code generation entrypoint:

// ent/entc.go
func main() {
    err := entc.Generate("./schema", &gen.Config{}, entc.Extensions(entds.NewEntDS()))
    if err != nil {
        log.Fatal(err)
    }
}

Then use the generated DataStorer to create entities:

tx, _ := client.Tx(ctx)

ds := ent.NewDataStorer(tx, 500) // 500 = batch size

// Create entities -- order doesn't matter
group := ds.CreateGroup().SetName("Engineering").Future()
user := ds.CreateUser().SetName("Alice").Future()

// Wire up relationships between futures
user.SetFutureFavGroup(group)
group.AddFutureMembers(user)

// Save resolves dependencies, bulk-inserts, and links edges
ds.Save(ctx)

tx.Commit()

Relationships can be set from either side of an edge. If you set a required edge via its inverse, entds redirects the assignment to the owning side automatically:

// These are equivalent -- entds handles the indirection
user.SetFutureFavGroup(group)
group.AddFutureFavoriteOf(user) // redirects to user.SetFutureFavGroup(group)

What Gets Generated

For each entity type in your schema, entds generates:

  • Future<Type> -- a wrapper that holds a reference to a not-yet-persisted entity and its pending relationships.
  • <type>DS -- the per-type storer responsible for bulk-creating entities and saving their edges.
  • DataStorer -- the top-level coordinator that topologically sorts types and orchestrates the save.
  • DependsOn -- a static dependency map derived from required edges, used for ordering.
  • Future() / SetFuture* / AddFuture* methods -- added to Ent's existing *Create builders so you can chain naturally.

Status

This is a prototype. The API works and the approach is sound, but it hasn't been battle-tested in production.

About

An Ent extension for batch-creating interconnected entities in a single transaction.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages