Closed rams3sh closed 2 years ago
(Note: I do not use gorm, and am only familiar with SQLite and the mattn wrapper.)
In SQLite, for historical reasons whether foreign keys are enabled is a property of an individual database connection, NOT the database itself. Consequently the fact that your DB Browser shows foreign keys enabled is irrelevant.
In order to enable foreign keys on your application's database connections, you will likely have to set a parameter in the DSN. Should be sqlite.Open("file:" + dbName+".db?_fk=1")
. See the mattn docs for more information.
@rittneje Thanks. Sure.
I understand that foreign key in sqlite is connection specific. The screenshot was shared just to show that it worked from the browser and not from gorm. This issue is very specific to gorm and not sqlite I feel.
sqlite.Open("file:" + dbName+".db?_fk=1")
according to my understanding is to be used only if you are dealing with sqlite package directly without an intermediate ORM interface. This connection string is expected to be handled by the gorm instead based on the tag provided in the struct field which is being done alrite in case of postgresql but no sqlite.
Hence this issue.
I don't see any logic in the source code to manipulate the connection string. It just passes it verbatim. For Postgres it works because I don't think you can disable foreign keys anyway.
It would be nice if gorm just always enabled foreign keys, regardless of whether your schema references them. But that might be a breaking change, for the same reason that SQLite itself considered it a breaking change.
BTW, another workaround for now is to compile with the sqlite_foreign_keys
tag, as that will enable foreign keys by default.
It would be nice if gorm just always enabled foreign keys, regardless of whether your schema references them. But that might be a breaking change, for the same reason that SQLite itself considered it a breaking change.
I think gorm can have foreign key enforce option applicable / considered only for sqlite with some default value handling for backward compatibility, and user can explicitly set that flag during initialisation.
Anyway I am just speculating and throwing of ideas from my head.
After updating gorm and gorm/sqlite I also stumbled upon this problem. Not including '?_fk=1' is only part of the problem as adding it to the example code makes no difference: create still does not return an error.
I think the other part of the problem is closely related to https://github.com/mattn/go-sqlite3/issues/986#issuecomment-983727930. When using a version of gorm/sqlite with RETURNING support (and only inserting a single struct), gorm itself calls rows.Next() once, scans the result but does not call rows.Next() again, resulting in the missing error. The fix in sqlite3 itself (https://sqlite.org/src/info/a818ba2ed635b91e) may resolve this issue, but it's not released yet. I'll try to patch it by hand and reverify the problem.
EDIT: Manually updating mattn/go-sqlite3 with the newest prerelease amalgamation code fixes this problem. Guess we have to wait for sqlite 3.38.0. (:
Otherwise, downgrading to 1.1.6 would also be an option: this is the latest Version without RETURNING support.
https://sqlite.org/foreignkeys.html
If it still doesn't work, try to run PRAGMA foreign_keys = ON
, the case should be tested in github.com/go-gorm/gorm
Sample Reproduction Code
I havent handled errors in the below program. I have written it with objective of reproducing the issue.
Output
Expectation
SQLITE3 should raise foreign key violation error just as postgresql.
Description
SQLite3 doesnt seem to honor foreign key constraint when provided with non existing foreign primary key id through gorm. However , postgres honors it. The above code tries to create a Node record with invalid Environment Id in sqlite3 and postgres database.
When the same is tried through the sqlite browser, it gives the error. Screenshot below :- :
The PRAGMA
Foreign Keys
is set to true. Screenshot from SQLITE3 browser below :-Raising the issue here since there is not much documentation that I could find pertaining to the above issue.
I have referred articles related to sqlite3 foreign key handling in gorm. Most of them pertained to old version and there was'nt much pertaining to v2 gorm. Hence raising the issue here.