Giter Site home page Giter Site logo

ent's Introduction

ent - An Entity Framework For Go

Twitter Discord

English | 中文 | 日本語 | 한국어

Simple, yet powerful entity framework for Go, that makes it easy to build and maintain applications with large data-models.

  • Schema As Code - model any database schema as Go objects.
  • Easily Traverse Any Graph - run queries, aggregations and traverse any graph structure easily.
  • Statically Typed And Explicit API - 100% statically typed and explicit API using code generation.
  • Multi Storage Driver - supports MySQL, MariaDB, TiDB, PostgreSQL, CockroachDB, SQLite and Gremlin.
  • Extendable - simple to extend and customize using Go templates.

Quick Installation

go install entgo.io/ent/cmd/ent@latest

For proper installation using Go modules, visit entgo.io website.

Docs and Support

The documentation for developing and using ent is available at: https://entgo.io

For discussion and support, open an issue or join our channel in the gophers Slack.

Join the ent Community

Building ent would not have been possible without the collective work of our entire community. We maintain a contributors page which lists the contributors to this ent.

In order to contribute to ent, see the CONTRIBUTING file for how to go get started. If your company or your product is using ent, please let us know by adding yourself to the ent users page.

For updates, follow us on Twitter at https://twitter.com/entgo_io

About the Project

The ent project was inspired by Ent, an entity framework we use internally. It is developed and maintained by a8m and alexsn from the Facebook Connectivity team. It is used by multiple teams and projects in production, and the roadmap for its v1 release is described here. Read more about the motivation of the project here.

License

ent is licensed under Apache 2.0 as found in the LICENSE file.

ent's People

Contributors

a8m avatar aca avatar adaynu avatar alexsn avatar allcontributors[bot] avatar brentchesny avatar cliedeman avatar crossworth avatar day-dreams avatar dependabot[bot] avatar giautm avatar hantmac avatar hedwigz avatar htdvisser avatar jeremyv2014 avatar kerbelp avatar kortschak avatar marwan-at-work avatar masseelch avatar napei avatar riskyferyansyahp avatar ronenlu avatar rotemtam avatar rubensayshi avatar sashamelentyev avatar tarrencev avatar tmc avatar utamori avatar yonidavidson avatar zeevmoney avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ent's Issues

B: Generator uses wrong import paths when targeting a different directory

The generator uses wrong import paths when targeting a different directory.

To reproduce:

  1. Create entity to ./schema at directory root

    entc init --target schema Test
  2. Generate code to a target directory

    entc generate --target ent ./schema

Directory structure should look like this:

  • ent/* (for generated files)
  • schema/test.go (entity file)
  • go.mod
  • go.sum
  • main.go

Program won't compile due to wrong import paths in ent/test_*.go files.

For example, the import path used in ent/test_query.go:

package sample

import (
    ...

	"gitlab.com/user/sample/predicate"
	"gitlab.com/user/sample/test"
)

When it should be:

package sample

import (
    ...

	"gitlab.com/user/sample/ent/predicate"
	"gitlab.com/user/sample/ent/test"
)

Q: how to add field to edge(relation)?

This looks great.. quite amazing.

It's a newbie question.
I have User / Groups entity. Users can join multiple groups, and groups can have multiple users. So I think it is M:M relation.
When I define edge between to entitys. user_groups table is automatically generated (mysql).
I need some thing like "role" data ( a user is admin in group ) between user - groups.
I think It is good to be included in user_groups(edge) table.
But I just can't find a way to add field to the edge. Do I have to create another entity for role?

entc generate failed

user.go

package schema

import (
	"github.com/facebookincubator/ent"
	"github.com/facebookincubator/ent/schema/edge"
	"github.com/facebookincubator/ent/schema/field"
)

// User holds the schema definition for the User entity.
type User struct {
	ent.Schema
}

// Fields of the User.
func (User) Fields() []ent.Field {
	return []ent.Field{
		field.Int("age"),
		field.String("name"),
	}
}

// Edges of the User.
func (User) Edges() []ent.Edge {
	return []ent.Edge{
		edge.To("friends", User.Type),
	}
}

run entc generate ./ent/schema is failed,only generate an empty folder.

$ entc generate ./ent/schema
entc/gen: write file C:\project\gowork\src\awesomeProject\ent\user_create.go: formatting source: C:\project\gowork\src\awesomeProject\e
nt\user_create.go:21:19: unknown escape sequence (and 1 more errors)

proposal: eager loading support

We open this task in order to get feedback for the generated-code API of eager loading.
The 3 requirements (maybe there are more) we thought about are:

  • Allow filter edges/relations (using .Where)
  • Get nested edges/relations
  • Limit/offset capabilities

A few examples here for what we thought about:

Add a With<EdgeName> method to the builder:

client.User.
  Query().
  Where(...).
  WithPets().                   // populate all user pets.
  WithGroups(group.HasAdmin()). // filter out groups without admin.
  All(ctx)

This example gets all users under a condition + their pets + their groups (with an admin).


What about getting all users + their groups (limit to X) + their admins (eager-loading with depth 2)?
I'm not sure how common this scenario, so I think either disable this, or add a With<Edge>Fn option for more flexible loading:

client.User.
  Query().
  Where(...).
  WithGroupsFn(func(q *ent.GroupQuery) {
    q.Where(...).Limit(X).WithAdmin()
  }).
  All(ctx)

Maybe we can change With<Edge> to behave like With<Edge>Fn and make the function to be an optional parameter.


The return type for eager loading:

We were thinking about the 2 options:

  • Add the schema edges as public fields in the generated struct (e.g. ent.User), and then populate the result into these fields.

  • Add another struct type (struct) for holding the schema edges. For example:

      type UserEdges struct {
         Pets []*Pet
         // ...
      }

    I'm not sure how this is supposed to handle nested eager-loading (User->Pets->Friends)?

examples/o2o2types: Error with MySQL 8.0

mellon@collie:demo $ go run ./ent/examples/o2o2types/
2019/12/09 10:36:21 user: User(id=4, age=30, name=Mashraki)
2019/12/09 10:36:21 card: Card(id=4, expired=Mon Dec  9 10:37:21 2019, number=1020)
2019/12/09 10:36:21 querying card: sql: Scan error on column index 1, name "expired": unsupported Scan, storing driver.Value type []uint8 into type *time.Time
exit status 1

mellon@collie:demo $ mysql --version
mysql  Ver 8.0.18 for osx10.15 on x86_64 (Homebrew)

Add a contribution documentation

  • Explain the project struct
  • How to add code to changes to each of the packages
  • Codegen after changes to loader, generator and test packages
  • Run integration tests

Please provide API that allow us to use our own DB object

Please provide API for us to inject our own *DB object.

This will require an interface of:

type SQLBasic interface {
    ExecContext(ctx context.Context, query string, args ...interface{}) (stdSql.Result, error)
    QueryContext(ctx context.Context, query string, args ...interface{}) (*Rows, error)
    QueryRowContext(ctx context.Context, query string, args ...interface{}) *Row
}

Maybe another interface for transactions (not required, if we can pass our own *Tx object)

Currently I can't use this package with my https://github.com/rocketlaunchr/mysql-go which is required to make long mysql queries cancellable (respect context cancellation)

Feature Request: Add mysql context cancellation

Some graph queries can be very time consuming. On a large dataset backed by MySQL, running a query to find all friends of friends of friends of friends can be very time consuming. It is beneficial to be able to cancel the query (including the underlying query within MySQL).

Due to the current API design (more specifically the dialect.Driver interface) which is unlikely to change, it is not possible to cancel a query using the assistance of an external package (due to the way stdSql.Rows works with regards to context cancelation).

Can you please implement cancellation directly into your mysql driver. It's actually quite simple to do and it will add enormous value to your package.

Here is an article explaining how to cancel mysql: https://medium.com/@rocketlaunchr.cloud/canceling-mysql-in-go-827ed8f83b30

Foreign Key Filtering/Retrieval

Given the following schema

// todo.go
type Todo struct {
	ent.Schema
}

func (Todo) Fields() []ent.Field {
	return []ent.Field{
		field.Text("text"),
		field.Bool("done").Default(false),
	}
}

func (Todo) Edges() []ent.Edge {
	return []ent.Edge{
		edge.From("user", User.Type).
			Ref("todos").
			Unique(),
	}
}
// user.go
type User struct {
	ent.Schema
}

func (User) Fields() []ent.Field {
	return []ent.Field{
		field.String("name").
			Default("unknown"),
	}
}

func (User) Edges() []ent.Edge {
	return []ent.Edge{
		edge.To("todos", Todo.Type),
	}
}

If I run the following code
todos, err := client.Todo.Query().All(ctx)

There is no easy way to retrieve the user_id field without sending an additional query for each row right now.

Use Case:
Graphql Query that returns users then uses a data loader to fetch users. Ideal SQL:

select name, done, user_id from todo;
select name from users where user_id in (1,2,3,4);

Option 1:
Remove edge relation and manage fk manually.

Easy, works right now but loses a lot of the advantages especially around filtering

Option 2:
Duplicate fk column:

func (Todo) Fields() []ent.Field {
	return []ent.Field{
		field.Text("text"),
		field.Int("user_id_fk").StorageKey("user_id"),
		field.Bool("done").Default(false),
	}

(user_id column name has to be used to prevent function collisions)

        previous declaration at ent/todo_create.go:29:6
ent/todo_update.go:72:23: (*TodoUpdate).SetUserID redeclared in this block
        previous declaration at ent/todo_update.go:41:6
ent/todo_update.go:254:27: (*TodoUpdateOne).SetUserID redeclared in this block
        previous declaration at ent/todo_update.go:223:6

This also breaks because we get conflicting column definitions

Option 3:
Embed a readonly fk column that can be used for queries and retrieval without joining on the users table.

type Todo struct {
	config `json:"-"`
	// ID of the ent.
	ID int `json:"id,omitempty"`
	// Text holds the value of the "text" field.
	Text string `json:"text,omitempty"`
	// UserIDFk holds the value of the "user_id_fk" field.
	UserIDFk int `json:"user_id_fk,omitempty"`
	// Done holds the value of the "done" field.
	Done bool `json:"done,omitempty"`
}

I haven't fully fleshed out this idea but a good precursor might be readonly fields. For example audit fields.

Approach to unit tests

I would like to know what are the recommended approaches to unit testing the generated client codes. There is a generated example test but for integration. I am pretty new to go and ent, but I thought of the following strategies:

  1. Move interactions on ent.Client to a separate layer e.g. using patterns like repository/DAO, then mock out that layer. However, I think that this is redundant.

  2. Move individual interactions on ent.Client to separate functions that can be overridden during tests. This is simple and doable for simple usages.

  3. Mock the generated client code by entc.

  4. Use a mock sql driver like (https://github.com/DATA-DOG/go-sqlmock), or sqlite. I think this is also redundant. I would like to use objects outside of ent, and perform integration tests on an actual database at ent layer.

proposal: Bulk API

It would be nice to have some way to create / insert multiple entities of the same type at once.

Add Indexes/Edges/Hooks to Mixin

Currently the Mixin interface only contains fields:

https://github.com/facebookincubator/ent/blob/4aa550a68f4055830819d553a529bfd3c6e016a4/ent.go#L132-L136

I think it would be nice to support indexes for the fields that are in the mixin, so that I could define something like:

type ColorMixin struct{}

func (ColorMixin) Fields() []ent.Field {
	return []ent.Field{
		field.String("color"),
	}
}

func (ColorMixin) Indexes() []ent.Index {
	return []ent.Index{
		index.Fields("color"),
	}
}

migrations with sqlite3

I have roughly the schema below, and on the second pass of Schema.Create, it gives this stack trace. I notice on the documentation near the trace it says sqlite3 can't be used in "append-only" mode because it's "just for testing". Is that the current state of things? If so I can just change my database targets.

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x50 pc=0x957333]

goroutine 1 [running]:
github.com/facebookincubator/ent/dialect/sql/schema.(*Migrate).changeSet(0xc00011f740, 0x0, 0x10b6c40, 0xc8f660, 0xc00015a860, 0xbb0ea2)
        /usergo/pkg/mod/github.com/facebookincubator/[email protected]/dialect/sql/schema/migrate.go:241 +0x63
github.com/facebookincubator/ent/dialect/sql/schema.(*Migrate).create(0xc00011f740, 0xc8f460, 0xc0000a0000, 0xc8f660, 0xc00015a860, 0x10b0920, 0x3, 0x3, 0xbd9320, 0xc00011f740)
        /usergo/pkg/mod/github.com/facebookincubator/[email protected]/dialect/sql/schema/migrate.go:121 +0x1b6
github.com/facebookincubator/ent/dialect/sql/schema.(*Migrate).Create(0xc00011f740, 0xc8f460, 0xc0000a0000, 0x10b0920, 0x3, 0x3, 0x0, 0x0)
        /usergo/pkg/mod/github.com/facebookincubator/[email protected]/dialect/sql/schema/migrate.go:104 +0x11f
github.com/tinyci/services/service/usersvc/ent/migrate.(*Schema).Create(0xc0000ab6c0, 0xc8f460, 0xc0000a0000, 0x0, 0x0, 0x0, 0x0, 0xc0000d0d80)
        /usergo/src/github.com/tinyci/services/service/usersvc/ent/migrate/migrate.go:48 +0x12a

Schema:

// User holds the schema definition for the User entity.
type User struct {
  ent.Schema
}

// Fields of the User.
func (User) Fields() []ent.Field {
  return []ent.Field{
    field.String("username").Immutable().Unique(),
    field.String("password"),
    field.Time("created_at").Immutable().Default(time.Now),
    field.Time("updated_at").Default(time.Now),
  }
}

// Edges of the User.
func (User) Edges() []ent.Edge {
  return []ent.Edge{
    edge.To("capabilities", Capability.Type),
    edge.To("tokens", AuthToken.Type),
  }
}

// Capability holds the schema definition for the Capabilities entity.
type Capability struct {
  ent.Schema
}

// Fields of the Capabilities.
func (Capability) Fields() []ent.Field {
  return []ent.Field{
    field.String("capability").Immutable().Unique(),
  }
}

// Edges of the Capabilities.
func (Capability) Edges() []ent.Edge {
  return []ent.Edge{
    edge.To("users", User.Type).Unique(),
  }
}


// AuthToken holds the schema definition for the AuthToken entity.
type AuthToken struct {
  ent.Schema
}

// Fields of the AuthToken.
func (AuthToken) Fields() []ent.Field {
  return []ent.Field{
    field.String("service").Immutable(),
    field.String("token").Sensitive(),
    field.Time("created_at").Immutable().Default(time.Now),
    field.Time("expires_at").Immutable().Nillable().Optional(),
  }
}

// Edges of the AuthToken.
func (AuthToken) Edges() []ent.Edge {
  return []ent.Edge{
    edge.To("user", User.Type).Required().Unique(),
  }
}

override id column

Is there a way to redeclare the id column as a custom string type?

If I put the following in my schema:

field.String("id").Unique()

The generated code ends up broken because it creates two declarations of "id", but furthermore it ignores the fact that it's a string, and declares it as an integer instead.

This might be related to the UUID discussions, but it would be great if we can define our own custom primary keys as strings that we provide at runtime.

Cannot run command entc init <name> outside go path

hi team, I'm a beginner for golang. I have got a problem when using it to generate schema.

  • first step: I create a new folder, change directory to it and run command go mod init
  • second step: I install entc framework using command go get github.com/facebookincubator/ent/cmd/entc
  • third step: I run command entc init User, but I have got a message -bash: entc: command not found

I already check inside gopath exists entc execute the file. Please help me resolve the issue. thanks

Indexes with only Edges

Given the following in ent/schema/:

func (PublicKey) Edges() []ent.Edge {
	return []ent.Edge{
		edge.From("user", User.Type).
			Ref("public_keys").
			Unique(),
	}
}

func (PublicKey) Indexes() []ent.Index {
	return []ent.Index{
		index.Edges("user"),
	}
}

entc generate refuses to create an index on the user_id column of public_keys, with the error:

entc/gen: invalid index for schema "PublicKey": missing fields

Perhaps this only makes sense for SQL databases, but it should be possible to configure an index on user_id, right?

It looks like making this possible only require a small change in

https://github.com/facebookincubator/ent/blob/4aa550a68f4055830819d553a529bfd3c6e016a4/entc/gen/type.go#L378-L382

I can submit a pull request, but importing/reviewing that would probably take more time than it would take the maintainers to push a commit, or pulling it into their work on #91.

Q: recommended way to add aditional constraint?

Hi, I'm trying to add additional constraint rule. But It seems impossible in ent.
Would you recommend a way to add it after Schema.Create() ?
Should I just not use it at all? And initalize schema in other way?

I need something like this.
user / project / role
role has constraint unique (user, project)

About performance

Hey guys:

I learned from the documentation that ent supports both SQL and Germlin.

Because of their structural differences, I want to know how their performance is when performing graph traversal.And the applicable scene of ent?

Thanks.

Postgres Extension

Hello,

I am interested in using this library with postgres. I took a stab at adding postgres but hit a wall with the builder. The mysql quote identifier (backtick) is hardcoded in the file. My first idea was to switch on the dialect but it is not available.

Examples:

Edit: ? for args is also an issue

Ciaran

Clever use of edges causes code gen failure

package schema

import (
        "github.com/facebookincubator/ent"
        "github.com/facebookincubator/ent/schema/edge"
        "github.com/facebookincubator/ent/schema/field"
)

// Ref holds the schema definition for the Ref entity.
type Ref struct {
        ent.Schema
}

// Fields of the Ref.
func (Ref) Fields() []ent.Field {
        return nil
}

// Edges of the Ref.
func (Ref) Edges() []ent.Edge {
        return []ent.Edge{
                edge.To("names", RefName.Type),
        }
}

// RefName holds the schema definition for the RefName entity.
type RefName struct {
        ent.Schema
}

// Fields of the RefName.
func (RefName) Fields() []ent.Field {
        return []ent.Field{
                field.String("name"),
                field.Bool("tag"),
        }
}

// Edges of the RefName.
func (RefName) Edges() []ent.Edge {
        return []ent.Edge{
                edge.From("ref", Ref.Type).Ref("names"),
        }
}

entc generate passes this with flying colors, but generates code which will not compile:

erikh@tinyci src/test% go install -v ./...                                                                                 [5:54]
test/migrate
# test/migrate
migrate/schema.go:36:2: RefNamesColumns redeclared in this block
        previous declaration at migrate/schema.go:23:2
migrate/schema.go:41:2: RefNamesTable redeclared in this block
        previous declaration at migrate/schema.go:29:2

Renaming the From edge ref to ref_names seems to resolve the issue.

Roadmap for v1

List of features/changes we want to finish before releasing an official v1 version:

  • PostgreSQL support - done
  • Eager loading - #91 - done
  • User defined IDs - #127 - done
  • Hooks - #377 - done
  • Bulk insert - done #236
  • OSS GraphQL integration - done (expected more work in the near future)
  • Privacy layer - done (see entgo.io/docs/privacy)
  • User defined types - WIP #277
    • Custom Go Type
    • Custom Dialect Type
    • "Other" type
    • Custom predicates (WIP)
  • JSON operations
    • Predicates and filters
    • Append support
  • Upsert and batch upsert (dialect specific)
  • Query hooks (interceptors) - #833
  • Better migration
  • Multi-level caching (Experimental solution ariga/entcache)
  • Cluster support (read replicas)
  • Horizontal sharding
  • Edge fields (metadata on edges)
  • Cascading deletion - #407
    • DDL support
    • Application-level support

Please note that this list is changing.

SQL contraints are not removed when field.Unique() is removed

If you define a field with a unique constraint it will properly set to the data-model

return []ent.Field{
   field.String("name").Unique(),
}

Now, remove the constraint:

return []ent.Field{
   field.String("name"),
}

That change will not be propagated to the database. You can still see the constraint defined:

CONSTRAINT users_name_key UNIQUE (name)

I observed this behavior with postgres. Not tested with Mysql.

proposal: Cursor-based pagination

The tool already includes support for pagination, but its limited to offset pagination which is known to be less optimal for fast-changing datasets. Support for cursor-based pagination would be awesome.

Unable to specify custom package name

I have this generate.go file in my ./internal/ent directory:

package ent

//go:generate go run github.com/facebookincubator/ent/cmd/entc generate --target=store ./schema

When i run go generate ./internal/ent from the root of my project, it generates ent files under ./internal/ent/store, but inside those files, for example client.go, the package is package ent, but it should be store.

table locking

is there any suggested way to do table locking through a transaction?

tks

B: Generator uses conflicting variable names in config()

When creating an entity that starts with "i", the index variable used in config conflicts with the struct variable.

For example:

  1. Create entity
    entc init Item
  2. Generate code
    entc generate ./ent/schema
  3. Run code
    go run main.go
    
  4. Result:
    ent/item.go:78:4: invalid operation: i[i] (type int does not support indexing)

Conflicting generated code:

func (i Items) config(cfg config) {
	for i := range i {
		i[i].config = cfg
	}
}

"i" variable of type Items conflicts with "i" variable for index

Generated files missing some package imports

The generator misses some imports when chaining 3 entities with edges.

Scenario with 3 simple entities:

Person -> Car -> Part

  1. Generate entities

    entc init Person Car Part
  2. Add edges

    person.go

    // Edges of the Person.
    func (Person) Edges() []ent.Edge {
        return []ent.Edge{
            edge.To("car", Car.Type),
        }
    }

    car.go

    // Edges of the Car.
    func (Car) Edges() []ent.Edge {
        return []ent.Edge{
            edge.To("part", Part.Type),
        }
    }

    part.go

    // Edges of the Part.
    func (Part) Edges() []ent.Edge {
        return nil
    }
  3. Generate files

    entc generate ./ent/schema
  4. Run program

    go run main.go
    
    # gitlab.com/user/test/ent
    ent/car_create.go:75:14: undefined: part
    ent/car_query.go:55:18: undefined: part
    ent/car_update.go:132:21: undefined: part
    ent/car_update.go:143:15: undefined: part
    ent/car_update.go:282:21: undefined: part
    ent/car_update.go:293:15: undefined: part

I'm not really familiar with graph databases and maybe I'm using it the wrong way.

Q: why SQL?

This looks quite interesting. I have been recently looking into graph db due to the needs of my current project. I ended up with Dgraph but I struggled to work with its API and their horrendous documentation so I abandoned it altogether and came up with a custom in-memory solution(I only truly needed edges so it worked out).

Anyhow, this project looks like it would be perfect api layer on top of something like dgraph or underlying kvdb(badger, bolt) that abstracts the complexity away from the developer.

RDBMS was really not made for graphs, hence I wonder why SQL as a starting point for this type of project?

"Quick Introduction" example wrong

In doc/md/getting-started.md under section Create Your Second Edge, it has example code for the Group type, but incorrectly shows the same code as User.

This;

<project>/ent/schema/group.go:

  import (
 	"log"
 
 	"github.com/facebookincubator/ent"
 	"github.com/facebookincubator/ent/schema/edge"
  )
 
  // Edges of the User.
  func (User) Edges() []ent.Edge {
 	return []ent.Edge{
 		edge.To("cars", Car.Type),
 		// create an inverse-edge called "groups" of type `Group`
 		// and reference it to the "users" edge (in Group schema)
 		// explicitly using the `Ref` method.
 		edge.From("groups", Group.Type).
 			Ref("users"),
 	}
  }

Should be something like;

<project>/ent/schema/group.go:

  import (
 	"log"
 
 	"github.com/facebookincubator/ent"
 	"github.com/facebookincubator/ent/schema/edge"
  )
 
  // Edges of the Group.
  func (Group) Edges() []ent.Edge {
 	return []ent.Edge{
 		edge.To("users", User.Type),
 	}
  }

bug fix:Can't get field comment

截屏2019-12-1610 34 53

If I want to get the comment of a Edge I failed because the Comment field not defined in the Descriptor. I fix it in #244.

I'm not sure if we need such an operation,please review it.Thanks!

Bind JSON object from API

Great project guys,
following your User/Cars example in documentation, consider this JSON body from a CRUD http API:

{
	"age": 30,
	"name": "Bob",
	"cars": [{
			"model": "Tesla"
		},
		{
			"model": "BMW"
		}
	]
}

which is the best way to bind this json to ent insert/update?

Question: order based on edge

I started using entgo for a new project and really like it so far. Nonetheless I can into a problem with respect to the order. So far entgo supports ordering based on fields, as the example shows:
users, err := client.User.Query(). Order(ent.Asc(user.FieldName)). All(ctx)
Is it also possible to order based on edges? I unsuccessfully tried this approach:
Query := storage.Db().Person. Query(). Where(person.DeletedAtIsNil()). Offset(*offset). Limit(*limit). Clone()
if orderByFirstname != nil && *orderByFirstname == "asc" { Query=Query.QueryFirstname().Order(ent.Asc(stringvalue.FieldValue)).QueryFirstnameHolder().Clone() }
Do you have suggestions on this issue?

Can't build the traversal example

Looks like the traversal example uses code from the 'start' example:

~ $ go get -v -u -d -t github.com/facebookincubator/ent
github.com/facebookincubator/ent (download)

~ $ cd `go env GOPATH`/src/github.com/facebookincubator/ent/examples/traversal
traversal $ go generate ./...
traversal $ go build -v
github.com/facebookincubator/ent/examples/traversal/ent
# github.com/facebookincubator/ent/examples/traversal/ent
ent/tx.go:41:3: cannot use "github.com/facebookincubator/ent/examples/start/ent/migrate".NewSchema(tx.config.driver) (type *"github.com/facebookincubator/ent/examples/start/ent/migrate".Schema) as type *"github.com/facebookincubator/ent/examples/traversal/ent/migrate".Schema in field value

entc generate fails with `undefined: field.TypeUUID`

Hi guys, I don't understand what I'm doing wrong, I don't have any field.TypeUUID in my schema

$ entc generate ./ent/schema
entc/load: # command-line-arguments
./entc_github.com_lfaoro_spark_ent_schema_1575076841.go:130:21: undefined: field.TypeUUID

I have a pretty simple schema, and I'm unable to debug this. Could you point me in the right direction?

// Card holds the schema definition for the Card entity.
type Card struct {
	ent.Schema
}

// Fields of the Card.
func (Card) Fields() []ent.Field {
	return []ent.Field{
		field.String("user_id"),
		field.Bytes("ciphered_card"),

		field.String("token"),
		field.String("hash").Unique(),
		field.String("request_ip"),
		field.String("user_agent"),
		field.Time("expires_on"),
		field.Time("auto_delete_on"),
		field.Uint32("first_six"),
		field.Uint32("last_four"),
	}
}

// Edges of the Card.
func (Card) Edges() []ent.Edge {
	return []ent.Edge{
		edge.To("metadata", Metadata.Type).
			Unique(),

	}
}

Field named "type" crashes on generation

Hello, first thanks for this wonderful project !

Im hitting this issue, when one of my fields is called type, it crashes on:

[1] $ go generate ./ent                                                                                                                                                                                                                                                                                                   
format file /path/to/code/test/ent/mymodel/model.go: /path/to/code/ent/mymodel/model.go:111:18: expected type, found 'type' (and 1 more errors)
exit status 1
ent/generate.go:3: running "go": exit status 1

MySQL with non-nullable foreign key columns

I have an existing database schema from which I create schema objects from. The foreign key columns in the existing schema are non-nullable. When I create a new child entity in a O2M relationship, MySQL throws an error like as follows:

Error 1364: Field 'user_id' doesn't have a default value

In the generated xxx_create.go sqlSave function, the foreign key columns seem to be set after insertion.

Is there some other way to make this compatible other than setting these foreign columns as nullable? I checked the generated migration script produced by ent and the foreign key columns are indeed nullable.

Any way to run raw SQL query?

I like statically typed APIs, but sometimes we need to run raw SQLs to get functionalities of specific RDBMS. Currently, I don't find any way to do that.

Question: Field Migrations

I am trying to implement migrations properly with ent. Let's assume we have an entity user. We already collected data in that table:

// User schema.
type User struct {
    ent.Schema
}

// Fields of the user.
func (User) Fields() []ent.Field {
    return []ent.Field{
        field.Int("age"),
        field.String("name"),
        field.String("username").
            Unique(),
    }
}

Now, I want to and a new field:

field.Time("create_time").Default(time.Now()),

The migration will fail with column \"create_time\" contains null values". I'd like to understand what your recommended way is? I see at least two options:

  1. Combine ent migration with custom logic:
  • allow nilable values when I add new fields
  • migrate data (or create the required ones)
  • change field to not-nilable
  1. manage sql migrations outside of ent

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.