Godot SQLite 外键

Godot SQLite Foreign Key

谁能告诉我如何在 Godot 中的两个 table 之间创建外键关系。我无法根据当前文档计算。

extends Node2D

const SQLite = preload("res://addons/godot-sqlite/bin/gdsqlite.gdns")

var save_path = "user://data.sqlite"
var db 

func _ready():

    
    db = SQLite.new()
    db.path = save_path
    db.foreign_keys = true
    db.open_db()
    
    db.create_table("dog_names", {
        "id": {"data_type": "int", "primary_key": true, "auto_increment": true},
        "first_name": {"data_type": "text"},
        "last_name": {"data_type": "text"},
    })
    
    db.create_table("owners", {
        "id": {"data_type": "int", "primary_key": true, "auto_increment": true}, 
        "name": {"data_type": "text"}
    })
    db.query("SELECT * FROM dog_names;")
    print(db.query_result[0]["first_name"])

基本上我只是想在 table 主人和 table 狗之间添加一个多对一的关系。 一个主人可以养很多只狗,但一只狗只能有一个主人。

谢谢

首先,您需要在打开数据库之前启用它们:

db.foreign_keys = true
# …
db.open_db()

然后您需要一个引用另一个 table 的字段,并添加一个 "foreign_key": "TABLE_NAME.FIELD_NAME" 形式的条目(data_type 必须匹配,引用的字段必须是 "primary_key": true"unique": true):

例如:

db.create_table("dog", {
        # …
        "owner_id": {"data_type": "int", "foreign_key": "owner.id"}
    })

这会让你们的关系更上一层楼。在这种情况下,狗有零个或一个主人(如果你想强制它必须有一个,你可以使用 "not_null": true)。 owner 有零到多条狗。


有了外键约束,当你插入或修改dogtable的记录时,owner_id字段必须匹配其中一个id owner table(或 null)上的记录数。

例如dogtable上的记录说owner_id123,那么owner上一定有记录table 其中 id123。它不会让您以违反该约束的方式插入或修改该值。

这样一旦您在数据库中插入数据,您就知道可以使用 owner_id 查询到 owner table:

var dog_query_str := "SELECT owner_id FROM dog;"
var owner_query_str := "SELECT name FROM owner WHERE id=?;"
db.query(dog_query_str)
for result in db.query_result:
    db.query_with_bindings(owner_query_str, [result["owner_id"]])
    print(db.query_result)

注意这里我用的是prepared statements.

或者您可以使用 JOIN:

var query_str := "SELECT name FROM dog JOIN owner ON dog.owner_id = owner.id;"
db.query(query_str)
print(db.query_result)

当然,您可以根据需要修改它。 SQLite支持的SQL语法请参考SQL As Understood By SQLite

那么这是从 foreign_key 关系中获取信息的 best/only 方式吗?

db.query("SELECT owner FROM dog_names;")
    print(db.query_result)
    print(db.query_result[0])
    var o = db.query_result[0]["owner"]
    print(o)
    var o_str = "SELECT name FROM owners WHERE id = {int};"
    var o_form = o_str.format({"int": o})
    db.query(o_form)
    print(db.query_result)