pop icon indicating copy to clipboard operation
pop copied to clipboard

Cannot set primary key ID when id type is int or int64

Open sebd71 opened this issue 5 years ago • 1 comments

Hello,

with a postgres connection (same issue at least with sqlite), if ID field is type int or int64 (ID int 'db:"id"' ); calling tx.Create with a preset ID is not possible. ID will be overwritten by create method. ( see dialect_postgresql.go#L64 and dialect_postgresql.go#L87 )

Is it possible to change and have the same behavior as UUID ?https://github.com/gobuffalo/pop/blob/d30b82d843cd997d3ae847267fb68069329fdaec/dialect_common.go#L71

A possible fix, would be to add a check like :

	switch keyType {
	case "int", "int64":
            if model.ID() != 0 {
               // keep current logic that allocate a new id value
            }

Here is a testcase that can be added to executors_test.go file that illustrate this problem :

func Test_Create_Single_Set_ID(t *testing.T) {
	if PDB == nil {
		t.Skip("skipping integration tests")
	}
	r := require.New(t)
	validationLogs = []string{}
	transaction(func(tx *Connection) {
		singleID := &SingleID{
			ID: 123456,
		}
		err := tx.Create(singleID)
		r.NoError(err)
		r.Equal(123456, singleID.ID)
	})
}

And here is the test output:

--- FAIL: Test_Create_Single_Set_ID (0.00s)
    executors_test.go:185: 
                Error Trace:    executors_test.go:185
                                                        pop_test.go:66
                                                        connection.go:166
                                                        pop_test.go:65
                                                        executors_test.go:179
                Error:          Not equal: 
                                expected: 123456
                                actual  : 1
                Test:           Test_Create_Single_Set_ID
FAIL
exit status 1
FAIL    github.com/gobuffalo/pop/v5     0.043s

sebd71 avatar Aug 21 '20 08:08 sebd71

Yeah, I think it could be considerable. However, also with the current behavior, the ID is a concept of rowid when it is an integer type basically. If you want to store your own meaningful ID in your database, having a separate identifier could be a workaround for now.

Something like

type Car struct {
    ID            int
    FactoryNumber int
}

sio4 avatar Sep 20 '22 05:09 sio4