Следите за новинками
в нашем Telegram канале. Жми, чтобы подписаться:)
⊗rsSpRlFr 229 of 288 menu
◀ ▶

Внешний ключ в Rust

Столбец с номером чужой строки можно закрепить ограничением внешнего ключа. Оно не дает записать номер, которого нет в родительской таблице, если движок действительно проверяет ссылку.

В SQLite проверку включают командой PRAGMA foreign_keys = ON на открытом соединении. Без нее вставка с несуществующим номером может пройти тихо, и связь в данных развалится.

Если проект еще без зависимости, из корня Cargo выполните:

cargo add rusqlite --features bundled

Создадим таблицы user и post со ссылкой REFERENCES user(id):

use rusqlite::{Connection, params}; fn demo() -> Result<(), rusqlite::Error> { let _ = std::fs::remove_file("app.db"); let conn = Connection::open("app.db")?; conn.execute("PRAGMA foreign_keys = ON", [])?; conn.execute( "CREATE TABLE user ( id INTEGER PRIMARY KEY, name TEXT NOT NULL )", [], )?; conn.execute( "CREATE TABLE post ( id INTEGER PRIMARY KEY, user_id INTEGER NOT NULL, title TEXT NOT NULL, FOREIGN KEY (user_id) REFERENCES user(id) )", [], )?; conn.execute("INSERT INTO user (name) VALUES (?1)", params!["ann"])?; conn.execute( "INSERT INTO post (user_id, title) VALUES (?1, ?2)", params![1, "note"], )?; Ok(()) } fn main() { match demo() { Ok(()) => println!("ok"), Err(e) => println!("{}", e), } }

На экране ok. Номер 1 в user_id совпал с существующим пользователем.

Попробуем записать пост с чужим номером:

use rusqlite::{Connection, params}; fn try_bad() -> Result<(), rusqlite::Error> { let _ = std::fs::remove_file("app.db"); let conn = Connection::open("app.db")?; conn.execute("PRAGMA foreign_keys = ON", [])?; conn.execute( "CREATE TABLE user ( id INTEGER PRIMARY KEY, name TEXT NOT NULL )", [], )?; conn.execute( "CREATE TABLE post ( id INTEGER PRIMARY KEY, user_id INTEGER NOT NULL, title TEXT NOT NULL, FOREIGN KEY (user_id) REFERENCES user(id) )", [], )?; match conn.execute( "INSERT INTO post (user_id, title) VALUES (?1, ?2)", params![99, "ghost"], ) { Ok(_) => { println!("saved"); Ok(()) } Err(e) => { println!("rejected"); Err(e) } } } fn main() { let _ = try_bad(); }

Даны таблицы:

CREATE TABLE user ( id INTEGER PRIMARY KEY, name TEXT NOT NULL ); CREATE TABLE post ( id INTEGER PRIMARY KEY, user_id INTEGER NOT NULL, title TEXT NOT NULL, FOREIGN KEY (user_id) REFERENCES user(id) ); INSERT INTO user (name) VALUES ('kim');

Включите проверку внешних ключей и добавьте пост "box" для пользователя с номером 1. Выведите done при успехе.

Даны те же таблицы и включенная проверка. Попробуйте вставить пост с user_id 50. При ошибке выведите bad id.

Скажите, зачем команду PRAGMA foreign_keys = ON нужно выполнять на каждом новом открытии app.db, а не один раз навсегда.

← →
↑
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить