pop
pop copied to clipboard
Cannot set primary key ID when id type is int or int64
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
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
}