Jak SQLx zmienia pracę z bazami danych w Rust
Wyobraź sobie taką sytuację: napisałeś złożone zapytanie SQL, skompilowałeś projekt w Rust, uruchomiłeś i... dostałeś błąd runtime, bo pomyliłeś nazwę kolumny lub zapomniałeś podać jeden argument. Denerwujące, prawda? Szczególnie w języku, który chlubi się bezpieczeństwem. Właśnie ten problem rozwiązuje SQLx.
Czym właściwie jest
SQLx to nie typowy ORM jak Hibernate czy SQLAlchemy. Twórcy nazywają go „zestawem narzędzi SQL”. Główną cechą projektu jest to, że waliduje zapytania SQL już na etapie kompilacji. Jeśli zrobisz literówkę w SELECT lub spróbujesz wstawić string tam, gdzie baza danych oczekuje liczby, kompilator Rust po prostu nie pozwoli zbudować pliku binarnego.
Projekt jest w pełni asynchroniczny i napisany w czystym Rust (z wyjątkiem sterownika SQLite, który korzysta z biblioteki C). Obsługuje PostgreSQL, MySQL i SQLite. Kiedyś była obsługa MSSQL, ale została usunięta w wersji 0.7, z obietnicą przepisania sterownika od nowa.
Walidacja zapytań na etapie kompilacji
To prawdopodobnie najsilniejsza strona tej biblioteki. Zamiast budować zapytania przez łańcuchy metod (DSL), jak robią to Diesel czy SeaORM, piszesz zwykły SQL wewnątrz makra.
Jak to działa? Podczas budowania SQLx łączy się z bazą danych (ścieżka jest określona w zmiennej środowiskowej DATABASE_URL), prosi o walidację zapytania i zwraca informacje o typach. Jeśli baza danych powie, że zapytanie jest poprawne, makro generuje anonimową strukturę z wynikami.
Przy okazji, jeśli nie chcesz, żeby serwer CI uderzał do rzeczywistej bazy danych za każdym razem podczas budowania, SQLx ma „tryb offline”. Przygotowujesz cache z metadanymi zapytań raz, a potem projekt buduje się bez połączenia sieciowego.
Asynchroniczność i wydajność
SQLx został zaprojektowany od podstaw z myślą o async/await. Nie próbuje naśladować synchronicznego API opakowanego w wątki. Biblioteka potrafi streamować dane: jeśli musisz wyeksportować milion wierszy, możesz je przetwarzać pojedynczo w miarę ich napływania z gniazda, bez jednoczesnego zapełniania całej pamięci.
Co ciekawe, projekt nie jest powiązany z konkretnym runtime'em. Możesz użyć tokio, async-std lub actix — wystarczy włączyć odpowiedni feature flag w Cargo.toml.
SQLx został zaprojektowany od podstaw z myślą o async/await. Nie próbuje naśladować synchronicznego API opakowanego w wątki. Biblioteka potrafi streamować dane: jeśli musisz wyeksportować milion wierszy, możesz je przetwarzać pojedynczo w miarę ich napływania z gniazda, bez jednoczesnego zapełniania całej pamięci.
Co ciekawe, projekt nie jest powiązany z konkretnym runtime'em. Możesz użyć tokio, async-std lub actix — wystarczy włączyć odpowiedni feature flag w Cargo.toml.
Dlaczego to nie jest ORM
SQLx nie ma znajomych koncepcji takich jak „modele
Powiązane projekty