Database

Database

A database is an organized collection of data, generally stored and accessed electronically from a computer system. Where databases are more complex they are often developed using formal design and modeling techniques.
Python  Library

Python Library

1660506840

Psycopg 3: A Modern Implementation Of A PostgreSQL Adapter for Python

Psycopg 3

Psycopg 3 is a modern implementation of a PostgreSQL adapter for Python.

Installation

Quick version:

pip install --upgrade pip               # upgrade pip to at least 20.3
pip install "psycopg[binary,pool]"      # install binary dependencies

For further information about installation please check the documentation.

Hacking

In order to work on the Psycopg source code you need to have the libpq PostgreSQL client library installed in the system. For instance, on Debian systems, you can obtain it by running:

sudo apt install libpq5

After which you can clone this repository:

git clone https://github.com/psycopg/psycopg.git
cd psycopg

Please note that the repository contains the source code of several Python packages: that's why you don't see a setup.py here. The packages may have different requirements:

  • The psycopg directory contains the pure python implementation of psycopg. The package has only a runtime dependency on the libpq, the PostgreSQL client library, which should be installed in your system.
  • The psycopg_c directory contains an optimization module written in C/Cython. In order to build it you will need a few development tools: please look at Local installation in the docs for the details.
  • The psycopg_pool directory contains the connection pools implementations. This is kept as a separate package to allow a different release cycle.

You can create a local virtualenv and install there the packages in development mode, together with their development and testing requirements:

python -m venv .venv
source .venv/bin/activate
pip install -e "./psycopg[dev,test]"    # for the base Python package
pip install -e ./psycopg_c              # for the C extension module
pip install -e ./psycopg_pool           # for the connection pool

Now hack away! You can use tox to validate the code:

pip install tox
tox -p4

and to run the tests:

psql -c 'create database psycopg_test'
export PSYCOPG_TEST_DSN="dbname=psycopg_test"
tox -c psycopg -s
tox -c psycopg_c -s

Please look at the commands definitions in the tox.ini files if you want to run some of them interactively: the dependency should be already in your virtualenv. Feel free to adapt these recipes if you follow a different development pattern.

Download details:

Author: psycopg
Source code: https://github.com/psycopg/psycopg
License: LGPL-3.0 license

#python #postgresql #database 

Psycopg 3: A Modern Implementation Of A PostgreSQL Adapter for Python
曾 俊

曾 俊

1660485000

使用 Diesel 与 SQLx 与 Rust 中的数据库交互

在本教程中,我们将探讨在 Rust 中与关系数据库交互时使用的两个库:Diesel 和 SQLx。

本文将使用一个简单的课堂数据库与学生一起演示每种方法。我们将使用 Diesel ORM 和 SQLx 执行 CRUD 操作。

要学习本教程,您需要具备Rust 的工作知识以及访问和使用 Rust、Rust 的构建系统和包管理器 Cargo以及 MySQL 服务器实例的能力。

什么是柴油?

Diesel 是一个支持 PostgreSQL、MySQL、SQLite 的 ORM。ORM 代表对象-关系映射。ORM 帮助面向对象的程序员抽象出关系数据库的细节。

ORM 附带查询构建器,因此您不必担心编写原始 SQL 查询。使用 ORM,您可以与关系数据库进行通信,就好像它们是面向对象的一样。

对于经验不足的开发人员,使用 ORM 可能会更好,因为 ORM 会优化 SQL 查询。ORM 还使您更不容易受到 SQL 注入攻击。

什么是 SQLx?

与 Diesel 不同,SQLx 不是 ORM。SQLx 是一个异步 Rust SQL crate,具有编译时 SQL 查询检查功能。它与数据库和运行时无关。

SQLx 支持连接池、跨平台开发、嵌套池、异步通知、传输层安全性和其他令人兴奋的特性。使用 SQLx 时,您必须自己制作 SQL 查询和迁移。

触及表面之后,让我们探索如何使用 Diesel 和 SQLx 与关系数据库进行交互。

柴油 ORM 入门

以下步骤演示了如何使用使用 Diesel ORM 的 Cargo 设置 Rust 项目。

使用 Diesel ORM 初始化新项目

第一步是通过运行以下命令来初始化项目:

cargo new -- lib classroom_diesel
cd classroom_diesel

在上面的代码中,我们设置了项目并将其命名为classroom_diesel。新的项目目录应如下所示:

./
│
├── src/
│   └── lib.rs
│
├── .gitignore
└── Cargo.toml

我们还需要使用项目中需要的依赖项更新Cargo.toml文件,如下所示:

[dependencies]
diesel = { version = "1.4.4", features = ["mysql"] }
dotenv = "0.15.0"

依赖帮助我们管理项目中的dotenv环境变量。

安装 Diesel CLI

Diesel 使用单独的 CLI 工具。它是一个独立的二进制文件;我们不需要将它作为依赖项添加到cargo.toml文件中。只需使用以下命令安装它:

cargo install diesel_cli

设置我们的 Diesel 环境

我们需要DATABASE_URL在我们的环境中设置一个变量。这就是 Diesel 知道要连接到哪个 MySQL 数据库的方式:

echo DATABASE_URL=mysql://<username>:<password>@localhost/<database>  > .env

编辑连接字符串以匹配您的本地数据库凭据。

您的项目目录现在将如下所示:

./
│
├── src/
│   └── lib.rs
│
├── .env
├── .gitignore
└── Cargo.toml

现在运行以下命令:

diesel setup

该命令将帮助我们设置数据库并创建一个空的迁移目录来管理数据库模式。

设置 Diesel 迁移

迁移帮助 ORM 跟踪数据库操作,例如添加字段或删除表。您可以将它们视为数据库的版本控制系统。

首先,让我们使用 Diesel CLI 为课堂应用程序创建一些迁移。理想情况下,我们应该有一个包含课堂学生数据的表格。
我们需要创建空的迁移文件,然后用 SQL 填充它们以创建表。

diesel migration generate create_students

您的文件树将类似于以下内容:

./
│
├── migrations/
│   │
│   ├── 2022-07-04-062521_create_students/
│   │   ├── down.sql
│   │   └── up.sql
│   │
│   └── .gitkeep
│
├── src/
│   └── lib.rs
│
├── .env
├── .gitignore
├── Cargo.toml
└── diesel.toml

up.sql文件用于创建迁移,而该down.sql文件用于反转它。

up.sql使用 SQL更新文件以进行迁移:

sql
CREATE TABLE students (
  id INTEGER AUTO_INCREMENT PRIMARY KEY,
  firstname VARCHAR(255) NOT NULL,
  lastname TEXT NOT NULL,
  age INTEGER NOT NULL
);

down.sql用可以反向迁移的 SQL修改文件:

sql
DROP TABLE students;

创建updown迁移后,我们需要在数据库上执行 SQL:

diesel migration run

我们可以开始编写 Rust 来对表执行查询。

使用 Diesel ORM 创建行

让我们编写代码以使用文件中设置的连接字符串建立与 MySQL 服务器的连接.env

#[macro_use]
extern crate diesel;
extern crate dotenv;

pub mod models;
pub mod schema;

use diesel::prelude::*;
use dotenv::dotenv;
use std::env;

pub fn create_connection() -> MysqlConnection {
    dotenv().ok();

    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
    MysqlConnection::establish(&database_url)
        .unwrap_or_else(|_| panic!("Error connecting to {}", database_url))
}

Students接下来,我们必须为表编写一个模型。模型是发生对象关系映射的地方。Students该模型将生成将表上的一行或多行转换为Student Rust 中的结构所需的代码。

cd ./src
touch model.rs

在我们刚刚创建的新model.rs文件中,添加以下内容:

use super::schema::students;

#[derive(Queryable)]
pub struct Student {
    pub id: i32,
    pub firstname: String,
    pub lastname: String,
    pub age: i32,
}

#[derive(Insertable)]
#[table_name = "students"]
pub struct NewStudent<'a> {
    pub firstname: &'a str,
    pub lastname: &'a str,
    pub age: &'a i32,
}

使用此模型,Students表中的信息将映射到 Rust 中的相应Student结构。该src文件夹现在应如下所示:

src/
├── lib.rs
├── models.rs
└── schema.rs

现在,我们可以编写一个脚本来添加一个学生:

cd src mkdir bin cd bin touch create_students.rs

在该create_students.rs文件中,我们可以调用之前编写的模型和函数来创建一个新学生:

extern crate classroom_diesel;
extern crate diesel;

use self::classroom_diesel::*;
fn main() {
    let connection = create_connection();
    let firstname = "John";
    let lastname = "Doe";
    let age: i32 = 64;

    let student = create_post(&connection, firstname, lastname, &age);
    println!(
        "Saved student {} with id {}",
        student.firstname, student.id
    );
}

该项目的结构现在看起来与此类似:

./
│
├── migrations/
│   │
│   ├── 2022-07-04-062521_create_students/
│   │   ├── down.sql
│   │   └── up.sql
│   │
│   └── .gitkeep
│
├── src/
│   │
│   ├── bin/
│   │   └── create_students.rs
│   │
│   ├── lib.rs
│   ├── models.rs
│   └── schema.rs
│
├── .env
├── .gitignore
├── Cargo.lock
├── Cargo.toml
└── diesel.toml

使用以下命令执行新脚本:

cargo run --bin create_students

正如您在下图中看到的,新的学生文件John已保存id1. 我们可以使用它id来查询 Rust 数据库,我们将在下一节中介绍。

将学生表映射到结构以在 Diesel ORM 中创建新学生文件的结果

使用 Diesel ORM 查询 Rust 数据库

在上一节中,我们回顾了如何使用 Diesel ORM 在 Rust 中写入数据库。了解查询或阅读的工作原理也很重要。

让我们编写一个脚本来查询一个学生id1. 首先创建一个query_students.rs文件:

cd bin
touch query_students.rs

然后,在query_students.rs我们刚刚创建的文件中,添加以下内容:

extern crate classroom_diesel;
extern crate diesel;

use self::models::*;
use classroom_diesel::*;
use diesel::prelude::*;

fn main() {
    use self::schema::students::dsl::*;

    let connection = create_connection();
    let result = students
        .filter(id.eq(1))
        .load::<Student>(&connection)
        .expect("Error loading students");

    println!(
        "Student: {} {} {} years",
        result[0].firstname, result[0].lastname, result[0].age
    );
}

执行脚本:

cargo run --bin query_students

如下图所示,结果是一个打印行,其中包含我们从数据库中查询的学生文件的名字、姓氏和年龄:

使用 Diesel ORM 从 Rust 数据库中查询学生文件的结果

SQLx 入门

现在我们知道如何创建一个使用 Diesel ORM 与 Rust 中的数据库交互的项目,让我们看看如何创建一个使用 SQLx 的项目。

使用 SQLx 初始化新项目

首先运行以下命令:

cargo new classroom_sqlx --bin

然后,将所需的依赖项添加到cargo.toml文件中:

[dependencies]
sqlx = { version = "0.5", features = [  "runtime-async-std-native-tls", "mysql" ] }
async-std = { version = "1", features = [ "attributes" ] }

这就是您在设置方面所需要的一切。很简单,对吧?

要使用 SQLx 与 Rust 中的数据库交互,我们所要做的就是编写一些 SQL 查询和 Rust 代码。在 Diesel ORM 部分,我们创建并读取了学生记录;在本节中,我们将编写查询来更新和删除记录。

使用 SQLx 和 Rust 更新或删除数据库记录

首先,我们需要编写一些 Rust 代码来将 SQLx 连接到 MySQL 服务器:

//main.rs

use sqlx::mysql::MySqlPoolOptions;

#[async_std::main]
async fn main() -> Result<(), sqlx::Error> {
    let pool = MySqlPoolOptions::new()
        .max_connections(7)
        .connect("mysql://root:@localhost/classroom_diesel")
        .await?;

    Ok(())
}

SQLx 支持准备好的和未准备好的 SQL 查询。准备好的 SQL 查询反对 SQL 注入。

让我们看看如何更新主键为 1 的记录的名字和姓氏:

use sqlx::mysql::MySqlPoolOptions;

#[async_std::main]
async fn main() -> Result<(), sqlx::Error> {
    let pool = MySqlPoolOptions::new()
        .max_connections(5)
        .connect("mysql://root:@localhost/classroom_diesel")
        .await?;

    sqlx::query("UPDATE students SET firstname=?, lastname=? WHERE id=?")
        .bind("Richard")
        .bind("Roe")
        .bind(1)
        .execute(&pool)
        .await?;
    Ok(())
}

使用以下命令执行脚本:

cargo run

删除记录也采用类似的模式;唯一的区别是 SQL 查询:

use sqlx::mysql::MySqlPoolOptions;

#[async_std::main]
async fn main() -> Result<(), sqlx::Error> {
    let pool = MySqlPoolOptions::new()
        .max_connections(5)
        .connect("mysql://root:@localhost/classroom_diesel")
        .await?;

    sqlx::query("DELETE FROM students WHERE id=?")
        .bind(1)
        .execute(&pool)
        .await?;
    Ok(())
}

使用以下命令执行脚本:

cargo run

现在,您可以使用 Diesel 或 SQLx 与 Rust 中的数据库进行交互。

结论

像 Diesel 这样的 ORM 就足够了;它们可以帮助您生成一些您需要的 SQL。大多数时候,足够的就是您的应用程序所需要的。

然而,在更广泛的应用程序中,可能需要更多的“魔法”——换句话说,你的时间和精力——才能使 ORM 正常工作并生成高性能的 SQL 查询。

如果需要创建具有高容量和低延迟要求的更复杂的查询,最好使用 SQLx 等库来执行原始 SQL 查询。

来源:https ://blog.logrocket.com/interacting-databases-rust-diesel-vs-sqlx/

    #rust #database 

使用 Diesel 与 SQLx 与 Rust 中的数据库交互
Iara  Simões

Iara Simões

1660482300

Interagindo Com Bancos De Dados Em Rust Usando Diesel Vs. SQLx

Neste tutorial, exploraremos duas bibliotecas usadas ao interagir com bancos de dados relacionais em Rust: Diesel e SQLx.

Este artigo usará um banco de dados de sala de aula simples com os alunos para demonstrar cada abordagem. Realizaremos operações CRUD usando Diesel ORM e SQLx.

Para acompanhar este tutorial, você precisará de um conhecimento prático do Rust , juntamente com a capacidade de acessar e usar o Rust, o sistema de compilação do Rust e o gerenciador de pacotes Cargo e uma instância do servidor MySQL.

O que é Diesel?

Diesel é um ORM que suporta PostgreSQL, MySQL, SQLite. ORM significa mapeamento relacional de objeto. Os ORMs ajudam os programadores orientados a objetos a abstrair os detalhes dos bancos de dados relacionais.

Os ORMs são fornecidos com construtores de consultas, portanto, você não precisa se preocupar em escrever consultas SQL brutas. Usando ORMs, você pode se comunicar com bancos de dados relacionais como se fossem orientados a objetos.

Para desenvolvedores menos experientes, o uso de ORMs pode ser melhor porque os ORMs criam consultas SQL otimizadas. Os ORMs também o tornam menos propenso a ataques de injeção de SQL.

O que é SQLx?

Ao contrário do Diesel, o SQLx não é um ORM. SQLx é uma caixa de Rust SQL assíncrona que apresenta verificações de consulta SQL em tempo de compilação. É independente de banco de dados e de tempo de execução.

O SQLx suporta pool de conexão, desenvolvimento multiplataforma, pool aninhado, notificações assíncronas, segurança da camada de transporte e outros recursos interessantes. Ao usar o SQLx, você mesmo deve criar as consultas e migrações SQL.

Tendo arranhado a superfície, vamos explorar como interagir com bancos de dados relacionais com Diesel e SQLx.

Introdução ao Diesel ORM

As etapas a seguir demonstram como configurar um projeto Rust com Cargo que usa Diesel ORM.

Inicializando um novo projeto com Diesel ORM

Sua primeira etapa é inicializar o projeto executando o seguinte comando:

cargo new -- lib classroom_diesel
cd classroom_diesel

No código acima, configuramos o projeto e o nomeamos classroom_diesel. O novo diretório do projeto deve ficar assim:

./
│
├── src/
│   └── lib.rs
│
├── .gitignore
└── Cargo.toml

Também precisamos atualizar o Cargo.tomlarquivo com as dependências que precisamos no projeto, assim:

[dependencies]
diesel = { version = "1.4.4", features = ["mysql"] }
dotenv = "0.15.0"

A dotenvdependência nos ajuda a gerenciar variáveis ​​de ambiente no projeto.

Instalando Diesel CLI

Diesel usa uma ferramenta CLI separada . É um binário autônomo; não precisamos adicioná-lo como uma dependência no cargo.tomlarquivo. Basta instalá-lo com o comando abaixo:

cargo install diesel_cli

Configurando nosso ambiente Diesel

Precisamos definir uma DATABASE_URLvariável em nosso ambiente. É assim que Diesel sabe a qual banco de dados MySQL se conectar:

echo DATABASE_URL=mysql://<username>:<password>@localhost/<database>  > .env

Edite a cadeia de conexão para corresponder às credenciais do banco de dados local.

O diretório do seu projeto agora ficará assim:

./
│
├── src/
│   └── lib.rs
│
├── .env
├── .gitignore
└── Cargo.toml

Agora execute o seguinte comando:

diesel setup

Este comando nos ajudará a configurar o banco de dados e criar um diretório de migrações vazio para gerenciar o esquema do banco de dados.

Como configurar migrações do Diesel

As migrações ajudam o ORM a acompanhar as operações do banco de dados, como adicionar um campo ou excluir uma tabela. Você pode pensar neles como um sistema de controle de versão para seu banco de dados.

Primeiro, vamos criar algumas migrações para o aplicativo de sala de aula usando o Diesel CLI. Idealmente, deveríamos ter uma tabela contendo dados sobre os alunos da sala de aula.
Precisamos criar arquivos de migração vazios e preenchê-los com SQL para criar uma tabela.

diesel migration generate create_students

Sua árvore de arquivos será semelhante a esta:

./
│
├── migrations/
│   │
│   ├── 2022-07-04-062521_create_students/
│   │   ├── down.sql
│   │   └── up.sql
│   │
│   └── .gitkeep
│
├── src/
│   └── lib.rs
│
├── .env
├── .gitignore
├── Cargo.toml
└── diesel.toml

O up.sqlarquivo é para criar uma migração, enquanto o down.sqlarquivo é para revertê-la.

Atualize o up.sqlarquivo com o SQL para a migração:

sql
CREATE TABLE students (
  id INTEGER AUTO_INCREMENT PRIMARY KEY,
  firstname VARCHAR(255) NOT NULL,
  lastname TEXT NOT NULL,
  age INTEGER NOT NULL
);

Modifique o down.sqlarquivo com SQL que pode reverter a migração:

sql
DROP TABLE students;

Após criar as migrações upe down, precisamos executar o SQL no banco de dados:

diesel migration run

Podemos começar a escrever Rust para realizar consultas na tabela.

Criando linhas com Diesel ORM

Vamos escrever o código para estabelecer uma conexão com o servidor MySQL usando a string de conexão definida no .envarquivo.

#[macro_use]
extern crate diesel;
extern crate dotenv;

pub mod models;
pub mod schema;

use diesel::prelude::*;
use dotenv::dotenv;
use std::env;

pub fn create_connection() -> MysqlConnection {
    dotenv().ok();

    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
    MysqlConnection::establish(&database_url)
        .unwrap_or_else(|_| panic!("Error connecting to {}", database_url))
}

Em seguida, devemos escrever um modelo para a Studentstabela. Os modelos são onde o mapeamento relacional de objeto ocorre. O modelo irá gerar o código necessário para converter uma linha ou linhas na Studentstabela em um Student struct em Rust .

cd ./src
touch model.rs

No novo model.rsarquivo que acabamos de criar, adicione o seguinte:

use super::schema::students;

#[derive(Queryable)]
pub struct Student {
    pub id: i32,
    pub firstname: String,
    pub lastname: String,
    pub age: i32,
}

#[derive(Insertable)]
#[table_name = "students"]
pub struct NewStudent<'a> {
    pub firstname: &'a str,
    pub lastname: &'a str,
    pub age: &'a i32,
}

Com este modelo, as informações da Studentstabela serão mapeadas para a Studentestrutura correspondente em Rust. A srcpasta agora deve ficar assim:

src/
├── lib.rs
├── models.rs
└── schema.rs

Agora, podemos escrever um script para adicionar um aluno:

cd src mkdir bin cd bin touch create_students.rs

No create_students.rsarquivo, podemos invocar os modelos e funções escritos anteriormente para criar um novo aluno:

extern crate classroom_diesel;
extern crate diesel;

use self::classroom_diesel::*;
fn main() {
    let connection = create_connection();
    let firstname = "John";
    let lastname = "Doe";
    let age: i32 = 64;

    let student = create_post(&connection, firstname, lastname, &age);
    println!(
        "Saved student {} with id {}",
        student.firstname, student.id
    );
}

A estrutura do projeto agora será semelhante a esta:

./
│
├── migrations/
│   │
│   ├── 2022-07-04-062521_create_students/
│   │   ├── down.sql
│   │   └── up.sql
│   │
│   └── .gitkeep
│
├── src/
│   │
│   ├── bin/
│   │   └── create_students.rs
│   │
│   ├── lib.rs
│   ├── models.rs
│   └── schema.rs
│
├── .env
├── .gitignore
├── Cargo.lock
├── Cargo.toml
└── diesel.toml

Execute o novo script usando o seguinte comando:

cargo run --bin create_students

Como você pode ver na imagem abaixo, o novo arquivo do aluno para Johnfoi salvo com uma extensão idde 1. Podemos usar isso idpara consultar bancos de dados Rust, que veremos na próxima seção.

Resultado do mapeamento da tabela de alunos para uma estrutura para criar um novo arquivo de aluno no Diesel ORM

Consulta de banco de dados Rust com Diesel ORM

Na seção anterior, revisamos como gravar no banco de dados em Rust usando Diesel ORM. Também é essencial entender como a consulta, ou leitura, funciona.

Vamos escrever um script para consultar um aluno cujo idé 1. Comece criando um query_students.rsarquivo:

cd bin
touch query_students.rs

Em seguida, no query_students.rsarquivo que acabamos de criar, adicione o seguinte:

extern crate classroom_diesel;
extern crate diesel;

use self::models::*;
use classroom_diesel::*;
use diesel::prelude::*;

fn main() {
    use self::schema::students::dsl::*;

    let connection = create_connection();
    let result = students
        .filter(id.eq(1))
        .load::<Student>(&connection)
        .expect("Error loading students");

    println!(
        "Student: {} {} {} years",
        result[0].firstname, result[0].lastname, result[0].age
    );
}

Execute o script:

cargo run --bin query_students

Como você pode ver na imagem abaixo, o resultado é uma linha impressa contendo o nome, sobrenome e idade do arquivo do aluno que consultamos no banco de dados:

Resultado da consulta de um arquivo de aluno de um banco de dados Rust usando Diesel ORM

Introdução ao SQLx

Agora que sabemos como criar um projeto que usa Diesel ORM para interagir com bancos de dados em Rust, vamos dar uma olhada em como criar um projeto que usa SQLx.

Inicializando um novo projeto com SQLx

Comece executando o comando abaixo:

cargo new classroom_sqlx --bin

Em seguida, adicione as dependências necessárias ao cargo.tomlarquivo:

[dependencies]
sqlx = { version = "0.5", features = [  "runtime-async-std-native-tls", "mysql" ] }
async-std = { version = "1", features = [ "attributes" ] }

Isso é tudo que você precisa com relação à configuração. Simples, certo?

Para usar o SQLx para interagir com bancos de dados em Rust, tudo o que precisamos fazer é escrever algumas consultas SQL e código Rust. Na seção Diesel ORM, criamos e lemos um registro do aluno; nesta seção, escreveremos consultas para atualizar e excluir um registro.

Usando SQLx e Rust para atualizar ou excluir registros do banco de dados

Primeiro, precisamos escrever algum código Rust para conectar o SQLx ao servidor MySQL:

//main.rs

use sqlx::mysql::MySqlPoolOptions;

#[async_std::main]
async fn main() -> Result<(), sqlx::Error> {
    let pool = MySqlPoolOptions::new()
        .max_connections(7)
        .connect("mysql://root:@localhost/classroom_diesel")
        .await?;

    Ok(())
}

SQLx suporta consultas SQL preparadas e não preparadas. As consultas SQL preparadas são avessas à injeção de SQL.

Vamos ver como atualizar o nome e o sobrenome de um registro com uma chave primária de 1:

use sqlx::mysql::MySqlPoolOptions;

#[async_std::main]
async fn main() -> Result<(), sqlx::Error> {
    let pool = MySqlPoolOptions::new()
        .max_connections(5)
        .connect("mysql://root:@localhost/classroom_diesel")
        .await?;

    sqlx::query("UPDATE students SET firstname=?, lastname=? WHERE id=?")
        .bind("Richard")
        .bind("Roe")
        .bind(1)
        .execute(&pool)
        .await?;
    Ok(())
}

Execute o script com o comando abaixo:

cargo run

A exclusão do registro também segue um padrão semelhante; a única diferença é a consulta SQL:

use sqlx::mysql::MySqlPoolOptions;

#[async_std::main]
async fn main() -> Result<(), sqlx::Error> {
    let pool = MySqlPoolOptions::new()
        .max_connections(5)
        .connect("mysql://root:@localhost/classroom_diesel")
        .await?;

    sqlx::query("DELETE FROM students WHERE id=?")
        .bind(1)
        .execute(&pool)
        .await?;
    Ok(())
}

Execute o script com o comando abaixo:

cargo run

Agora você pode interagir com bancos de dados em Rust usando Diesel ou SQLx.

Conclusão

ORMs como Diesel são adequados; eles ajudam a gerar parte do SQL de que você precisa. Na maioria das vezes, adequado é tudo o que você precisa em suas aplicações.

No entanto, pode levar mais “mágica” – em outras palavras, seu tempo e esforço – em aplicativos mais extensos para que os ORMs funcionem corretamente e gerem consultas SQL de alto desempenho.

Se surgir a necessidade de criar consultas mais complicadas com requisitos de alto volume e baixa latência, pode ser melhor usar bibliotecas como SQLx para executar consultas SQL brutas.

Fonte: https://blog.logrocket.com/interacting-databases-rust-diesel-vs-sqlx/

  #rust #database 

Interagindo Com Bancos De Dados Em Rust Usando Diesel Vs. SQLx
Léon  Peltier

Léon Peltier

1660481340

interagir Avec Des Bases De Données Dans Rust

Dans ce didacticiel, nous allons explorer deux bibliothèques utilisées lors de l'interaction avec des bases de données relationnelles dans Rust : Diesel et SQLx.

Cet article utilisera une simple base de données de classe avec des étudiants pour démontrer chaque approche. Nous effectuerons des opérations CRUD en utilisant Diesel ORM et SQLx.

Pour suivre ce didacticiel, vous aurez besoin d'une connaissance pratique de Rust ainsi que de la capacité d'accéder à Rust et de l'utiliser, du système de construction et du gestionnaire de packages Cargo de Rust , ainsi que d'une instance de serveur MySQL.

Qu'est-ce que le diesel ?

Diesel est un ORM qui prend en charge PostgreSQL, MySQL, SQLite. ORM signifie mappage objet-relationnel. Les ORM aident les programmeurs orientés objet à résumer les détails des bases de données relationnelles.

Les ORM sont livrés avec des générateurs de requêtes, vous n'avez donc pas à vous soucier d'écrire des requêtes SQL brutes. En utilisant les ORM, vous pouvez communiquer avec des bases de données relationnelles comme si elles étaient orientées objet.

Pour les développeurs moins expérimentés, l'utilisation des ORM peut être préférable car les ORM élaborent des requêtes SQL optimisées. Les ORM vous rendent également moins sujet aux attaques par injection SQL.

Qu'est-ce que SQLx ?

Contrairement à Diesel, SQLx n'est pas un ORM. SQLx est un crate Rust SQL asynchrone qui propose des vérifications de requêtes SQL au moment de la compilation. Il est à la fois indépendant de la base de données et de l'exécution.

SQLx prend en charge le regroupement de connexions, le développement multiplateforme, le regroupement imbriqué, les notifications asynchrones, la sécurité de la couche de transport et d'autres fonctionnalités intéressantes. Lorsque vous utilisez SQLx, vous devez créer vous-même les requêtes SQL et les migrations.

Après avoir effleuré la surface, explorons comment interagir avec les bases de données relationnelles avec Diesel et SQLx.

Premiers pas avec Diesel ORM

Les étapes suivantes montrent comment configurer un projet Rust avec Cargo qui utilise Diesel ORM.

Initialisation d'un nouveau projet avec Diesel ORM

La première étape consiste à initialiser le projet en exécutant la commande suivante :

cargo new -- lib classroom_diesel
cd classroom_diesel

Dans le code ci-dessus, nous avons configuré le projet et l'avons nommé classroom_diesel. Le nouveau répertoire du projet devrait ressembler à ceci :

./
│
├── src/
│   └── lib.rs
│
├── .gitignore
└── Cargo.toml

Nous devons également mettre à jour le Cargo.tomlfichier avec les dépendances dont nous avons besoin dans le projet, comme ceci :

[dependencies]
diesel = { version = "1.4.4", features = ["mysql"] }
dotenv = "0.15.0"

La dotenvdépendance nous aide à gérer les variables d'environnement dans le projet.

Installation de la CLI diesel

Diesel utilise un outil CLI séparé . C'est un binaire autonome ; nous n'avons pas besoin de l'ajouter en tant que dépendance dans le cargo.tomlfichier. Installez-le simplement avec la commande ci-dessous :

cargo install diesel_cli

Mise en place de notre environnement Diesel

Nous devons définir une DATABASE_URLvariable dans notre environnement. C'est ainsi que Diesel sait à quelle base de données MySQL se connecter :

echo DATABASE_URL=mysql://<username>:<password>@localhost/<database>  > .env

Modifiez la chaîne de connexion pour qu'elle corresponde aux informations d'identification de votre base de données locale.

Votre répertoire de projet ressemblera maintenant à ceci :

./
│
├── src/
│   └── lib.rs
│
├── .env
├── .gitignore
└── Cargo.toml

Exécutez maintenant la commande suivante :

diesel setup

Cette commande nous aidera à configurer la base de données et à créer un répertoire de migrations vide pour gérer le schéma de la base de données.

Mise en place des migrations Diesel

Les migrations aident l'ORM à suivre les opérations de la base de données, telles que l'ajout d'un champ ou la suppression d'une table. Vous pouvez les considérer comme un système de contrôle de version pour votre base de données.

Commençons par créer des migrations pour l'application de classe à l'aide de Diesel CLI. Idéalement, nous devrions avoir un tableau contenant des données sur les élèves de la classe.
Nous devons créer des fichiers de migration vides, puis les remplir avec SQL pour créer une table.

diesel migration generate create_students

Votre arborescence de fichiers ressemblera à ceci :

./
│
├── migrations/
│   │
│   ├── 2022-07-04-062521_create_students/
│   │   ├── down.sql
│   │   └── up.sql
│   │
│   └── .gitkeep
│
├── src/
│   └── lib.rs
│
├── .env
├── .gitignore
├── Cargo.toml
└── diesel.toml

Le up.sqlfichier sert à créer une migration, tandis que le down.sqlfichier sert à l'inverser.

Mettez à jour le up.sqlfichier avec le SQL pour la migration :

sql
CREATE TABLE students (
  id INTEGER AUTO_INCREMENT PRIMARY KEY,
  firstname VARCHAR(255) NOT NULL,
  lastname TEXT NOT NULL,
  age INTEGER NOT NULL
);

Modifiez le down.sqlfichier avec SQL qui peut inverser la migration :

sql
DROP TABLE students;

Après avoir créé les migrations upet down, nous devons exécuter le SQL sur la base de données :

diesel migration run

Nous pouvons commencer à écrire Rust pour effectuer des requêtes sur la table.

Création de rangées avec Diesel ORM

Écrivons du code pour établir une connexion au serveur MySQL en utilisant la chaîne de connexion définie dans le .envfichier.

#[macro_use]
extern crate diesel;
extern crate dotenv;

pub mod models;
pub mod schema;

use diesel::prelude::*;
use dotenv::dotenv;
use std::env;

pub fn create_connection() -> MysqlConnection {
    dotenv().ok();

    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
    MysqlConnection::establish(&database_url)
        .unwrap_or_else(|_| panic!("Error connecting to {}", database_url))
}

Ensuite, nous devons écrire un modèle pour la Studentstable. Les modèles sont l'endroit où le mappage objet-relationnel a lieu. Le modèle générera le code nécessaire pour convertir une ou plusieurs lignes de la Studentstable en une Student structure dans Rust .

cd ./src
touch model.rs

Dans le nouveau model.rsfichier que nous venons de créer, ajoutez ce qui suit :

use super::schema::students;

#[derive(Queryable)]
pub struct Student {
    pub id: i32,
    pub firstname: String,
    pub lastname: String,
    pub age: i32,
}

#[derive(Insertable)]
#[table_name = "students"]
pub struct NewStudent<'a> {
    pub firstname: &'a str,
    pub lastname: &'a str,
    pub age: &'a i32,
}

Avec ce modèle, les informations de la Studentstable seront mappées à la structure correspondante Studentdans Rust. Le srcdossier devrait maintenant ressembler à ceci :

src/
├── lib.rs
├── models.rs
└── schema.rs

Maintenant, nous pouvons écrire un script pour ajouter un étudiant :

cd src mkdir bin cd bin tactile create_students.rs

Dans le create_students.rsfichier, nous pouvons invoquer les modèles et fonctions écrits précédemment pour créer un nouvel étudiant :

extern crate classroom_diesel;
extern crate diesel;

use self::classroom_diesel::*;
fn main() {
    let connection = create_connection();
    let firstname = "John";
    let lastname = "Doe";
    let age: i32 = 64;

    let student = create_post(&connection, firstname, lastname, &age);
    println!(
        "Saved student {} with id {}",
        student.firstname, student.id
    );
}

La structure du projet ressemblera maintenant à ceci :

./
│
├── migrations/
│   │
│   ├── 2022-07-04-062521_create_students/
│   │   ├── down.sql
│   │   └── up.sql
│   │
│   └── .gitkeep
│
├── src/
│   │
│   ├── bin/
│   │   └── create_students.rs
│   │
│   ├── lib.rs
│   ├── models.rs
│   └── schema.rs
│
├── .env
├── .gitignore
├── Cargo.lock
├── Cargo.toml
└── diesel.toml

Exécutez le nouveau script à l'aide de la commande suivante :

cargo run --bin create_students

Comme vous pouvez le voir dans l'image ci-dessous, le nouveau fichier étudiant pour Johna été enregistré avec l' idextension 1. Nous pouvons l'utiliser idpour interroger les bases de données Rust, que nous examinerons dans la section suivante.

Résultat du mappage de la table des étudiants sur une structure pour créer un nouveau fichier étudiant dans Diesel ORM

Interrogation de la base de données Rust avec Diesel ORM

Dans la section précédente, nous avons examiné comment écrire dans la base de données de Rust à l'aide de Diesel ORM. Il est également essentiel de comprendre comment l'interrogation, ou la lecture, fonctionne.

Écrivons un script pour interroger un étudiant dont idest 1. Commencez par créer un query_students.rsfichier :

cd bin
touch query_students.rs

Ensuite, dans le query_students.rsfichier que nous venons de créer, ajoutez ce qui suit :

extern crate classroom_diesel;
extern crate diesel;

use self::models::*;
use classroom_diesel::*;
use diesel::prelude::*;

fn main() {
    use self::schema::students::dsl::*;

    let connection = create_connection();
    let result = students
        .filter(id.eq(1))
        .load::<Student>(&connection)
        .expect("Error loading students");

    println!(
        "Student: {} {} {} years",
        result[0].firstname, result[0].lastname, result[0].age
    );
}

Exécutez le script :

cargo run --bin query_students

Comme vous pouvez le voir dans l'image ci-dessous, le résultat est une ligne imprimée contenant le prénom, le nom et l'âge du dossier étudiant que nous avons interrogé dans la base de données :

Résultat de l'interrogation d'un fichier étudiant à partir d'une base de données Rust à l'aide de Diesel ORM

Premiers pas avec SQLx

Maintenant que nous savons comment créer un projet qui utilise Diesel ORM pour interagir avec des bases de données dans Rust, voyons comment créer un projet qui utilise SQLx à la place.

Initialiser un nouveau projet avec SQLx

Commencez par exécuter la commande ci-dessous :

cargo new classroom_sqlx --bin

Ajoutez ensuite les dépendances requises au cargo.tomlfichier :

[dependencies]
sqlx = { version = "0.5", features = [  "runtime-async-std-native-tls", "mysql" ] }
async-std = { version = "1", features = [ "attributes" ] }

C'est tout ce dont vous avez besoin pour la mise en place. Simple, non ?

Pour utiliser SQLx pour interagir avec les bases de données dans Rust, tout ce que nous avons à faire est d'écrire des requêtes SQL et du code Rust. Dans la section Diesel ORM, nous avons créé et lu un dossier étudiant; dans cette section, nous allons écrire des requêtes pour mettre à jour et supprimer un enregistrement.

Utiliser SQLx et Rust pour mettre à jour ou supprimer des enregistrements de base de données

Tout d'abord, nous devons écrire du code Rust pour connecter SQLx au serveur MySQL :

//main.rs

use sqlx::mysql::MySqlPoolOptions;

#[async_std::main]
async fn main() -> Result<(), sqlx::Error> {
    let pool = MySqlPoolOptions::new()
        .max_connections(7)
        .connect("mysql://root:@localhost/classroom_diesel")
        .await?;

    Ok(())
}

SQLx prend en charge les requêtes SQL préparées et non préparées. Les requêtes SQL préparées sont opposées à l'injection SQL.

Voyons comment mettre à jour le prénom et le nom d'un enregistrement avec une clé primaire de 1 :

use sqlx::mysql::MySqlPoolOptions;

#[async_std::main]
async fn main() -> Result<(), sqlx::Error> {
    let pool = MySqlPoolOptions::new()
        .max_connections(5)
        .connect("mysql://root:@localhost/classroom_diesel")
        .await?;

    sqlx::query("UPDATE students SET firstname=?, lastname=? WHERE id=?")
        .bind("Richard")
        .bind("Roe")
        .bind(1)
        .execute(&pool)
        .await?;
    Ok(())
}

Exécutez le script avec la commande ci-dessous :

cargo run

La suppression de l'enregistrement suit également un schéma similaire ; la seule différence est la requête SQL :

use sqlx::mysql::MySqlPoolOptions;

#[async_std::main]
async fn main() -> Result<(), sqlx::Error> {
    let pool = MySqlPoolOptions::new()
        .max_connections(5)
        .connect("mysql://root:@localhost/classroom_diesel")
        .await?;

    sqlx::query("DELETE FROM students WHERE id=?")
        .bind(1)
        .execute(&pool)
        .await?;
    Ok(())
}

Exécutez le script avec la commande ci-dessous :

cargo run

Vous pouvez désormais interagir avec les bases de données dans Rust en utilisant Diesel ou SQLx.

Conclusion

Les ORM comme Diesel sont adéquats ; ils vous aident à générer une partie du SQL dont vous avez besoin. La plupart du temps, vous n'avez besoin que d'adéquat dans vos applications.

Cependant, cela peut prendre plus de "magie" - en d'autres termes, votre temps et vos efforts - dans des applications plus étendues pour que les ORM fonctionnent correctement et génèrent des requêtes SQL performantes.

S'il s'avère nécessaire de créer des requêtes plus complexes avec des exigences de volume élevé et de faible latence, il peut être préférable d'utiliser des bibliothèques comme SQLx pour exécuter des requêtes SQL brutes.

Source : https://blog.logrocket.com/interacting-databases-rust-diesel-vs-sqlx/

   #rust #database 

interagir Avec Des Bases De Données Dans Rust
Saul  Alaniz

Saul Alaniz

1660481280

Interactuar Con Bases De Datos En Rust Usando Diesel Vs. SQLx

En este tutorial, exploraremos dos bibliotecas utilizadas al interactuar con bases de datos relacionales en Rust: Diesel y SQLx.

Este artículo utilizará una base de datos de aula simple con estudiantes para demostrar cada enfoque. Realizaremos operaciones CRUD usando Diesel ORM y SQLx.

Para seguir este tutorial, necesitará un conocimiento práctico de Rust junto con la capacidad de acceder y usar Rust, el sistema de compilación de Rust y el administrador de paquetes Cargo , y una instancia de servidor MySQL.

¿Qué es Diésel?

Diesel es un ORM que soporta PostgreSQL, MySQL, SQLite. ORM significa mapeo relacional de objetos. Los ORM ayudan a los programadores orientados a objetos a abstraer los detalles de las bases de datos relacionales.

Los ORM se envían con generadores de consultas, por lo que no tiene que preocuparse por escribir consultas SQL sin formato. Con los ORM, puede comunicarse con bases de datos relacionales como si estuvieran orientadas a objetos.

Para los desarrolladores menos experimentados, el uso de ORM podría ser mejor porque los ORM crean consultas SQL optimizadas. Los ORM también lo hacen menos propenso a los ataques de inyección SQL.

¿Qué es SQLx?

A diferencia de Diesel, SQLx no es un ORM. SQLx es una caja asíncrona de Rust SQL que presenta verificaciones de consultas SQL en tiempo de compilación. Es independiente tanto de la base de datos como del tiempo de ejecución.

SQLx admite la agrupación de conexiones, el desarrollo multiplataforma, la agrupación anidada, las notificaciones asincrónicas, la seguridad de la capa de transporte y otras características interesantes. Al usar SQLx, debe crear las consultas SQL y las migraciones usted mismo.

Habiendo arañado la superficie, exploremos cómo interactuar con bases de datos relacionales con Diesel y SQLx.

Primeros pasos con ORM diésel

Los siguientes pasos demuestran cómo configurar un proyecto de Rust con Cargo que usa Diesel ORM.

Inicializando un nuevo proyecto con Diesel ORM

Su primer paso es inicializar el proyecto ejecutando el siguiente comando:

cargo new -- lib classroom_diesel
cd classroom_diesel

En el código anterior, configuramos el proyecto y lo llamamos classroom_diesel. El nuevo directorio del proyecto debería verse así:

./
│
├── src/
│   └── lib.rs
│
├── .gitignore
└── Cargo.toml

También necesitamos actualizar el Cargo.tomlarchivo con las dependencias que necesitamos en el proyecto, así:

[dependencies]
diesel = { version = "1.4.4", features = ["mysql"] }
dotenv = "0.15.0"

La dotenvdependencia nos ayuda a administrar las variables de entorno en el proyecto.

Instalación de Diesel CLI

Diesel usa una herramienta CLI separada . Es un binario independiente; no necesitamos agregarlo como una dependencia en el cargo.tomlarchivo. Simplemente instálelo con el siguiente comando:

cargo install diesel_cli

Configurando nuestro entorno Diesel

Necesitamos establecer una DATABASE_URLvariable en nuestro entorno. Así es como Diesel sabe a qué base de datos MySQL conectarse:

echo DATABASE_URL=mysql://<username>:<password>@localhost/<database>  > .env

Edite la cadena de conexión para que coincida con las credenciales de su base de datos local.

El directorio de su proyecto ahora se verá así:

./
│
├── src/
│   └── lib.rs
│
├── .env
├── .gitignore
└── Cargo.toml

Ahora ejecuta el siguiente comando:

diesel setup

Este comando nos ayudará a configurar la base de datos y crear un directorio de migraciones vacío para administrar el esquema de la base de datos.

Configuración de migraciones diésel

Las migraciones ayudan al ORM a realizar un seguimiento de las operaciones de la base de datos, como agregar un campo o eliminar una tabla. Puede pensar en ellos como un sistema de control de versiones para su base de datos.

Primero, creemos algunas migraciones para la aplicación del salón de clases usando Diesel CLI. Idealmente, deberíamos tener una tabla que contenga datos sobre los estudiantes del salón de clases.
Necesitamos crear archivos de migración vacíos, luego llenarlos con SQL para crear una tabla.

diesel migration generate create_students

Su árbol de archivos se verá similar a esto:

./
│
├── migrations/
│   │
│   ├── 2022-07-04-062521_create_students/
│   │   ├── down.sql
│   │   └── up.sql
│   │
│   └── .gitkeep
│
├── src/
│   └── lib.rs
│
├── .env
├── .gitignore
├── Cargo.toml
└── diesel.toml

El up.sqlarchivo es para crear una migración, mientras que el down.sqlarchivo es para revertirla.

Actualice el up.sqlarchivo con el SQL para la migración:

sql
CREATE TABLE students (
  id INTEGER AUTO_INCREMENT PRIMARY KEY,
  firstname VARCHAR(255) NOT NULL,
  lastname TEXT NOT NULL,
  age INTEGER NOT NULL
);

Modifique el down.sqlarchivo con SQL que puede revertir la migración:

sql
DROP TABLE students;

Después de crear las upmigraciones down, necesitamos ejecutar el SQL en la base de datos:

diesel migration run

Podemos comenzar a escribir Rust para realizar consultas en la tabla.

Creando filas con Diesel ORM

Escribamos código para establecer una conexión con el servidor MySQL utilizando la cadena de conexión establecida en el .envarchivo.

#[macro_use]
extern crate diesel;
extern crate dotenv;

pub mod models;
pub mod schema;

use diesel::prelude::*;
use dotenv::dotenv;
use std::env;

pub fn create_connection() -> MysqlConnection {
    dotenv().ok();

    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
    MysqlConnection::establish(&database_url)
        .unwrap_or_else(|_| panic!("Error connecting to {}", database_url))
}

A continuación, debemos escribir un modelo para la Studentstabla. Los modelos son donde tiene lugar el mapeo relacional de objetos. El modelo generará el código necesario para convertir una fila o filas de la Studentstabla en una Student estructura en Rust .

cd ./src
touch model.rs

En el nuevo model.rsarchivo que acabamos de crear, agregue lo siguiente:

use super::schema::students;

#[derive(Queryable)]
pub struct Student {
    pub id: i32,
    pub firstname: String,
    pub lastname: String,
    pub age: i32,
}

#[derive(Insertable)]
#[table_name = "students"]
pub struct NewStudent<'a> {
    pub firstname: &'a str,
    pub lastname: &'a str,
    pub age: &'a i32,
}

Con este modelo, la información de la Studentstabla se asignará a la estructura correspondiente Studenten Rust. La srccarpeta ahora debería verse así:

src/
├── lib.rs
├── models.rs
└── schema.rs

Ahora, podemos escribir un script para agregar un estudiante:

cd src mkdir bin cd bin touch create_students.rs

En el create_students.rsarchivo, podemos invocar los modelos y funciones escritos anteriormente para crear un nuevo estudiante:

extern crate classroom_diesel;
extern crate diesel;

use self::classroom_diesel::*;
fn main() {
    let connection = create_connection();
    let firstname = "John";
    let lastname = "Doe";
    let age: i32 = 64;

    let student = create_post(&connection, firstname, lastname, &age);
    println!(
        "Saved student {} with id {}",
        student.firstname, student.id
    );
}

La estructura del proyecto ahora se verá similar a esto:

./
│
├── migrations/
│   │
│   ├── 2022-07-04-062521_create_students/
│   │   ├── down.sql
│   │   └── up.sql
│   │
│   └── .gitkeep
│
├── src/
│   │
│   ├── bin/
│   │   └── create_students.rs
│   │
│   ├── lib.rs
│   ├── models.rs
│   └── schema.rs
│
├── .env
├── .gitignore
├── Cargo.lock
├── Cargo.toml
└── diesel.toml

Ejecute el nuevo script usando el siguiente comando:

cargo run --bin create_students

Como puede ver en la imagen a continuación, el nuevo archivo de estudiante Johnse ha guardado con una extensión idde 1. Podemos usar esto idpara consultar las bases de datos de Rust, que veremos en la siguiente sección.

Resultado de la asignación de la tabla de estudiantes a una estructura para crear un nuevo archivo de estudiante en Diesel ORM

Consulta de la base de datos de Rust con Diesel ORM

En la sección anterior, revisamos cómo escribir en la base de datos en Rust usando Diesel ORM. También es esencial comprender cómo funciona la consulta o la lectura.

Escribamos un script para consultar a un estudiante cuyo ides 1. Comience creando un query_students.rsarchivo:

cd bin
touch query_students.rs

Luego, en el query_students.rsarchivo que acabamos de crear, agregue lo siguiente:

extern crate classroom_diesel;
extern crate diesel;

use self::models::*;
use classroom_diesel::*;
use diesel::prelude::*;

fn main() {
    use self::schema::students::dsl::*;

    let connection = create_connection();
    let result = students
        .filter(id.eq(1))
        .load::<Student>(&connection)
        .expect("Error loading students");

    println!(
        "Student: {} {} {} years",
        result[0].firstname, result[0].lastname, result[0].age
    );
}

Ejecute el script:

cargo run --bin query_students

Como puede ver en la imagen a continuación, el resultado es una línea impresa que contiene el nombre, el apellido y la edad del archivo del estudiante que consultamos en la base de datos:

Resultado de consultar un archivo de estudiante desde una base de datos de Rust usando Diesel ORM

Primeros pasos con SQLx

Ahora que sabemos cómo crear un proyecto que use Diesel ORM para interactuar con bases de datos en Rust, echemos un vistazo a cómo crear un proyecto que use SQLx en su lugar.

Inicializar un nuevo proyecto con SQLx

Comience ejecutando el siguiente comando:

cargo new classroom_sqlx --bin

Luego, agregue las dependencias requeridas al cargo.tomlarchivo:

[dependencies]
sqlx = { version = "0.5", features = [  "runtime-async-std-native-tls", "mysql" ] }
async-std = { version = "1", features = [ "attributes" ] }

Eso es todo lo que necesita con respecto a la configuración. Sencillo, ¿verdad?

Para usar SQLx para interactuar con bases de datos en Rust, todo lo que tenemos que hacer es escribir algunas consultas SQL y código Rust. En la sección Diesel ORM, creamos y leímos un registro de estudiante; en esta sección, escribiremos consultas para actualizar y eliminar un registro.

Uso de SQLx y Rust para actualizar o eliminar registros de la base de datos

Primero, necesitamos escribir algo de código Rust para conectar SQLx al servidor MySQL:

//main.rs

use sqlx::mysql::MySqlPoolOptions;

#[async_std::main]
async fn main() -> Result<(), sqlx::Error> {
    let pool = MySqlPoolOptions::new()
        .max_connections(7)
        .connect("mysql://root:@localhost/classroom_diesel")
        .await?;

    Ok(())
}

SQLx admite consultas SQL preparadas y no preparadas. Las consultas SQL preparadas son reacias a la inyección de SQL.

Veamos cómo actualizar el nombre y apellido de un registro con una clave principal de 1:

use sqlx::mysql::MySqlPoolOptions;

#[async_std::main]
async fn main() -> Result<(), sqlx::Error> {
    let pool = MySqlPoolOptions::new()
        .max_connections(5)
        .connect("mysql://root:@localhost/classroom_diesel")
        .await?;

    sqlx::query("UPDATE students SET firstname=?, lastname=? WHERE id=?")
        .bind("Richard")
        .bind("Roe")
        .bind(1)
        .execute(&pool)
        .await?;
    Ok(())
}

Ejecute el script con el siguiente comando:

cargo run

Eliminar el registro también sigue un patrón similar; la única diferencia es la consulta SQL:

use sqlx::mysql::MySqlPoolOptions;

#[async_std::main]
async fn main() -> Result<(), sqlx::Error> {
    let pool = MySqlPoolOptions::new()
        .max_connections(5)
        .connect("mysql://root:@localhost/classroom_diesel")
        .await?;

    sqlx::query("DELETE FROM students WHERE id=?")
        .bind(1)
        .execute(&pool)
        .await?;
    Ok(())
}

Ejecute el script con el siguiente comando:

cargo run

Ahora puede interactuar con bases de datos en Rust utilizando Diesel o SQLx.

Conclusión

Los ORM como Diesel son adecuados; lo ayudan a generar parte del SQL que necesita. La mayoría de las veces, adecuado es todo lo que necesita en sus aplicaciones.

Sin embargo, puede tomar más "magia", en otras palabras, su tiempo y esfuerzo, en aplicaciones más extensas para que los ORM funcionen correctamente y generen consultas SQL de alto rendimiento.

Si surge la necesidad de crear consultas más complicadas con requisitos de alto volumen y baja latencia, puede ser mejor usar bibliotecas como SQLx para ejecutar consultas SQL sin formato.

Fuente: https://blog.logrocket.com/interacting-databases-rust-diesel-vs-sqlx/

 #rust #database 

Interactuar Con Bases De Datos En Rust Usando Diesel Vs. SQLx
伊藤  直子

伊藤 直子

1660477560

Diesel と SQLx を使用して Rust でデータベースを操作する

このチュートリアルでは、Rust でリレーショナル データベースを操作するときに使用される 2 つのライブラリ、Diesel と SQLx について説明します。

この記事では、学生と一緒に簡単な教室データベースを使用して、各アプローチを示します。Diesel ORM と SQLx を使用して CRUD 操作を実行します。

このチュートリアルを進めるには、Rust の実用的な知識と、Rust、 Rust のビルド システムおよびパッケージ マネージャーである Cargo、および MySQL サーバー インスタンスにアクセスして使用する能力が必要です。

ディーゼルとは?

Diesel は、PostgreSQL、MySQL、SQLite をサポートする ORM です。ORM は、オブジェクト リレーショナル マッピングの略です。ORM は、オブジェクト指向プログラマーがリレーショナル データベースの詳細を抽象化するのに役立ちます。

ORM にはクエリ ビルダーが同梱されているため、未加工の SQL クエリの記述について心配する必要はありません。ORM を使用すると、オブジェクト指向であるかのようにリレーショナル データベースと通信できます。

ORM は最適化された SQL クエリを作成するため、経験の浅い開発者にとっては、ORM を使用する方がよい場合があります。また、ORM を使用すると、SQL インジェクション攻撃を受けにくくなります。

SQLx とは何ですか?

Diesel とは異なり、SQLx は ORM ではありません。SQLx は、コンパイル時の SQL クエリ チェックを特徴とする非同期 Rust SQL クレートです。データベースとランタイムの両方に依存しません。

SQLx は、接続プーリング、クロスプラットフォーム開発、ネストされたプーリング、非同期通知、トランスポート層セキュリティ、およびその他の優れた機能をサポートしています。SQLx を使用する場合、SQL クエリと移行を自分で作成する必要があります。

表面をなぞったところで、Diesel と SQLx を使用してリレーショナル データベースを操作する方法を見ていきましょう。

Diesel ORM の概要

次の手順は、Diesel ORM を使用する Cargo で Rust プロジェクトをセットアップする方法を示しています。

Diesel ORM を使用した新しいプロジェクトの初期化

最初のステップは、次のコマンドを実行してプロジェクトを初期化することです。

cargo new -- lib classroom_diesel
cd classroom_diesel

上記のコードでは、プロジェクトをセットアップして名前を付けましたclassroom_diesel。新しいプロジェクト ディレクトリは次のようになります。

./
│
├── src/
│   └── lib.rs
│
├── .gitignore
└── Cargo.toml

Cargo.toml次のように、プロジェクトで必要な依存関係でファイルを更新する必要もあります。

[dependencies]
diesel = { version = "1.4.4", features = ["mysql"] }
dotenv = "0.15.0"

依存関係は、プロジェクトで環境変数を管理するのdotenvに役立ちます。

Diesel CLI のインストール

Diesel は別の CLI ツールを使用します。これはスタンドアロンのバイナリです。ファイルに依存関係として追加する必要はありませんcargo.toml。以下のコマンドで簡単にインストールできます。

cargo install diesel_cli

ディーゼル環境のセットアップ

DATABASE_URL環境に変数を設定する必要があります。これは、どの MySQL データベースに接続するかを Diesel が認識する方法です。

echo DATABASE_URL=mysql://<username>:<password>@localhost/<database>  > .env

ローカル データベースの資格情報と一致するように接続文字列を編集します。

プロジェクト ディレクトリは次のようになります。

./
│
├── src/
│   └── lib.rs
│
├── .env
├── .gitignore
└── Cargo.toml

次のコマンドを実行します。

diesel setup

このコマンドは、データベースをセットアップし、データベース スキーマを管理するための空の移行ディレクトリを作成するのに役立ちます。

Diesel 移行の設定

移行は、ORM がフィールドの追加やテーブルの削除などのデータベース操作を追跡するのに役立ちます。データベースのバージョン管理システムと考えることができます。

まず、Diesel CLI を使用してクラスルーム アプリケーションの移行をいくつか作成しましょう。理想的には、教室の生徒に関するデータを含むテーブルが必要です。
空の移行ファイルを作成し、それらに SQL を入力してテーブルを作成する必要があります。

diesel migration generate create_students

ファイル ツリーは次のようになります。

./
│
├── migrations/
│   │
│   ├── 2022-07-04-062521_create_students/
│   │   ├── down.sql
│   │   └── up.sql
│   │
│   └── .gitkeep
│
├── src/
│   └── lib.rs
│
├── .env
├── .gitignore
├── Cargo.toml
└── diesel.toml

up.sqlファイルは移行を作成するためのもので、ファイルdown.sqlはそれを元に戻すためのものです。

up.sql移行用の SQL でファイルを更新します。

sql
CREATE TABLE students (
  id INTEGER AUTO_INCREMENT PRIMARY KEY,
  firstname VARCHAR(255) NOT NULL,
  lastname TEXT NOT NULL,
  age INTEGER NOT NULL
);

down.sql移行を元に戻すことができる SQL でファイルを変更します。

sql
DROP TABLE students;

updown移行を作成したら、データベースで SQL を実行する必要があります。

diesel migration run

Rust を書き始めて、テーブルに対してクエリを実行できます。

Diesel ORM で行を作成する

.envファイルに設定された接続文字列を使用して、MySQL サーバーへの接続を確立するコードを書きましょう。

#[macro_use]
extern crate diesel;
extern crate dotenv;

pub mod models;
pub mod schema;

use diesel::prelude::*;
use dotenv::dotenv;
use std::env;

pub fn create_connection() -> MysqlConnection {
    dotenv().ok();

    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
    MysqlConnection::establish(&database_url)
        .unwrap_or_else(|_| panic!("Error connecting to {}", database_url))
}

次に、Studentsテーブルのモデルを作成する必要があります。モデルは、オブジェクト リレーショナル マッピングが行われる場所です。Studentsモデルは、テーブルの 1 つまたは複数の行をStudent Rust の構造体に変換するために必要なコードを生成します。

cd ./src
touch model.rs

作成したばかりの新しいmodel.rsファイルに、次を追加します。

use super::schema::students;

#[derive(Queryable)]
pub struct Student {
    pub id: i32,
    pub firstname: String,
    pub lastname: String,
    pub age: i32,
}

#[derive(Insertable)]
#[table_name = "students"]
pub struct NewStudent<'a> {
    pub firstname: &'a str,
    pub lastname: &'a str,
    pub age: &'a i32,
}

このモデルでは、テーブルからの情報が RustStudentsの対応する構造体にマップされます。Studentフォルダは次のsrcようになります。

src/
├── lib.rs
├── models.rs
└── schema.rs

これで、生徒を追加するスクリプトを作成できます。

cd src mkdir bin cd bin touch create_students.rs

このcreate_students.rsファイルでは、以前に作成したモデルと関数を呼び出して、新しい生徒を作成できます。

extern crate classroom_diesel;
extern crate diesel;

use self::classroom_diesel::*;
fn main() {
    let connection = create_connection();
    let firstname = "John";
    let lastname = "Doe";
    let age: i32 = 64;

    let student = create_post(&connection, firstname, lastname, &age);
    println!(
        "Saved student {} with id {}",
        student.firstname, student.id
    );
}

プロジェクトの構造は次のようになります。

./
│
├── migrations/
│   │
│   ├── 2022-07-04-062521_create_students/
│   │   ├── down.sql
│   │   └── up.sql
│   │
│   └── .gitkeep
│
├── src/
│   │
│   ├── bin/
│   │   └── create_students.rs
│   │
│   ├── lib.rs
│   ├── models.rs
│   └── schema.rs
│
├── .env
├── .gitignore
├── Cargo.lock
├── Cargo.toml
└── diesel.toml

次のコマンドを使用して、新しいスクリプトを実行します。

cargo run --bin create_students

下の画像でわかるように、 の新しい学生ファイルJohnは. これを使用して Rust データベースにクエリを実行できます。これについては、次のセクションで説明します。id1id

ディーゼルORMで新しい学生ファイルを作成するために学生テーブルを構造体にマッピングした結果

Diesel ORM を使用した Rust データベースのクエリ

前のセクションでは、Diesel ORM を使用して Rust でデータベースに書き込む方法を確認しました。また、クエリまたは読み取りがどのように機能するかを理解することも不可欠です。

idが である学生にクエリを実行するスクリプトを作成しましょう1query_students.rsファイルの作成から始めます。

cd bin
touch query_students.rs

次に、query_students.rs作成したばかりのファイルに次を追加します。

extern crate classroom_diesel;
extern crate diesel;

use self::models::*;
use classroom_diesel::*;
use diesel::prelude::*;

fn main() {
    use self::schema::students::dsl::*;

    let connection = create_connection();
    let result = students
        .filter(id.eq(1))
        .load::<Student>(&connection)
        .expect("Error loading students");

    println!(
        "Student: {} {} {} years",
        result[0].firstname, result[0].lastname, result[0].age
    );
}

スクリプトを実行します。

cargo run --bin query_students

下の画像でわかるように、結果は、データベースからクエリした学生ファイルの名、姓、および年齢を含む出力行です。

Diesel ORM を使用して Rust データベースから学生ファイルをクエリした結果

SQLx の概要

Diesel ORM を使用して Rust のデータベースと対話するプロジェクトを作成する方法がわかったので、代わりに SQLx を使用するプロジェクトを作成する方法を見てみましょう。

SQLx を使用した新しいプロジェクトの初期化

以下のコマンドを実行して開始します。

cargo new classroom_sqlx --bin

次に、必要な依存関係をcargo.tomlファイルに追加します。

[dependencies]
sqlx = { version = "0.5", features = [  "runtime-async-std-native-tls", "mysql" ] }
async-std = { version = "1", features = [ "attributes" ] }

セットアップに関して必要なのはこれだけです。シンプルですね。

SQLx を使用して Rust のデータベースと対話するには、いくつかの SQL クエリと Rust コードを記述するだけです。Diesel ORM セクションでは、生徒の記録を作成して読み取りました。このセクションでは、レコードを更新および削除するためのクエリを記述します。

SQLx と Rust を使用してデータベース レコードを更新または削除する

まず、SQLx を MySQL サーバーに接続するための Rust コードを書く必要があります。

//main.rs

use sqlx::mysql::MySqlPoolOptions;

#[async_std::main]
async fn main() -> Result<(), sqlx::Error> {
    let pool = MySqlPoolOptions::new()
        .max_connections(7)
        .connect("mysql://root:@localhost/classroom_diesel")
        .await?;

    Ok(())
}

SQLx は、準備された SQL クエリと準備されていない SQL クエリの両方をサポートしています。準備された SQL クエリは、SQL インジェクションを嫌います。

主キーが 1 のレコードの姓名を更新する方法を見てみましょう。

use sqlx::mysql::MySqlPoolOptions;

#[async_std::main]
async fn main() -> Result<(), sqlx::Error> {
    let pool = MySqlPoolOptions::new()
        .max_connections(5)
        .connect("mysql://root:@localhost/classroom_diesel")
        .await?;

    sqlx::query("UPDATE students SET firstname=?, lastname=? WHERE id=?")
        .bind("Richard")
        .bind("Roe")
        .bind(1)
        .execute(&pool)
        .await?;
    Ok(())
}

以下のコマンドでスクリプトを実行します。

cargo run

レコードの削除も同様のパターンを取ります。唯一の違いは SQL クエリです。

use sqlx::mysql::MySqlPoolOptions;

#[async_std::main]
async fn main() -> Result<(), sqlx::Error> {
    let pool = MySqlPoolOptions::new()
        .max_connections(5)
        .connect("mysql://root:@localhost/classroom_diesel")
        .await?;

    sqlx::query("DELETE FROM students WHERE id=?")
        .bind(1)
        .execute(&pool)
        .await?;
    Ok(())
}

以下のコマンドでスクリプトを実行します。

cargo run

これで、Diesel または SQLx のいずれかを使用して、Rust のデータベースと対話できます。

結論

Diesel のような ORM で十分です。これらは、必要な SQL の一部を生成するのに役立ちます。ほとんどの場合、アプリケーションで必要なのは十分です。

ただし、より大規模なアプリケーションで ORM を正しく機能させ、パフォーマンスの高い SQL クエリを生成するには、より多くの「魔法」、つまり時間と労力が必要になる場合があります。

大量かつ低レイテンシの要件を持つより複雑なクエリを作成する必要が生じた場合は、SQLx などのライブラリを使用して生の SQL クエリを実行する方がよい場合があります。

ソース: https://blog.logrocket.com/interacting-databases-rust-diesel-vs-sqlx/

 #rust #database 

Diesel と SQLx を使用して Rust でデータベースを操作する
Duong Tran

Duong Tran

1660477440

Tương Tác Với Cơ Sở Dữ Liệu Trong Rust Bằng Diesel So Với SQLx

Trong hướng dẫn này, chúng ta sẽ khám phá hai thư viện được sử dụng khi tương tác với cơ sở dữ liệu quan hệ trong Rust: Diesel và SQLx.

Bài viết này sẽ sử dụng một cơ sở dữ liệu lớp học đơn giản với học sinh để chứng minh từng cách tiếp cận. Chúng tôi sẽ thực hiện các hoạt động CRUD bằng Diesel ORM và SQLx.

Để làm theo hướng dẫn này, bạn sẽ cần có kiến ​​thức làm việc về Rust cùng với khả năng truy cập và sử dụng Rust, hệ thống xây dựng của Rust và trình quản lý gói Cargo , và một phiên bản máy chủ MySQL.

Diesel là gì?

Diesel là một ORM hỗ trợ PostgreSQL, MySQL, SQLite. ORM là viết tắt của ánh xạ quan hệ đối tượng. ORM giúp các lập trình viên hướng đối tượng tóm tắt các chi tiết của cơ sở dữ liệu quan hệ.

ORM được vận chuyển cùng với các trình tạo truy vấn, vì vậy bạn không phải lo lắng về việc viết các truy vấn SQL thô. Sử dụng ORM, bạn có thể giao tiếp với cơ sở dữ liệu quan hệ như thể chúng là hướng đối tượng.

Đối với các nhà phát triển ít kinh nghiệm, sử dụng ORM có thể tốt hơn vì ORM tạo ra các truy vấn SQL được tối ưu hóa. ORM cũng giúp bạn ít bị tấn công SQL injection hơn.

SQLx là gì?

Không giống như Diesel, SQLx không phải là ORM. SQLx là thùng SQL Rust không đồng bộ có tính năng kiểm tra truy vấn SQL thời gian biên dịch. Nó vừa là cơ sở dữ liệu - vừa là bất khả tri thời gian chạy.

SQLx hỗ trợ gộp kết nối, phát triển đa nền tảng, gộp lồng nhau, thông báo không đồng bộ, bảo mật lớp truyền tải và các tính năng thú vị khác. Khi sử dụng SQLx, bạn phải tự tạo các truy vấn SQL và di chuyển.

Sau khi hoàn thành bề mặt, chúng ta hãy khám phá cách tương tác với cơ sở dữ liệu quan hệ với Diesel và SQLx.

Bắt đầu với Diesel ORM

Các bước sau đây trình bày cách thiết lập dự án Rust với Cargo sử dụng Diesel ORM.

Khởi tạo một dự án mới với Diesel ORM

Bước đầu tiên của bạn là khởi tạo dự án bằng cách chạy lệnh sau:

cargo new -- lib classroom_diesel
cd classroom_diesel

Trong đoạn mã trên, chúng tôi thiết lập dự án và đặt tên cho nó classroom_diesel. Thư mục dự án mới sẽ giống như sau:

./
│
├── src/
│   └── lib.rs
│
├── .gitignore
└── Cargo.toml

Chúng tôi cũng cần cập nhật Cargo.tomltệp với các phụ thuộc chúng tôi cần trong dự án, như sau:

[dependencies]
diesel = { version = "1.4.4", features = ["mysql"] }
dotenv = "0.15.0"

Sự dotenvphụ thuộc giúp chúng ta quản lý các biến môi trường trong dự án.

Cài đặt Diesel CLI

Diesel sử dụng một công cụ CLI riêng biệt . Nó là một nhị phân độc lập; chúng tôi không cần phải thêm nó như một phụ thuộc trong cargo.tomltệp. Chỉ cần cài đặt nó bằng lệnh dưới đây:

cargo install diesel_cli

Thiết lập môi trường Diesel của chúng tôi

Chúng ta cần thiết lập một DATABASE_URLbiến trong môi trường của chúng ta. Đây là cách Diesel biết cơ sở dữ liệu MySQL nào cần kết nối:

echo DATABASE_URL=mysql://<username>:<password>@localhost/<database>  > .env

Chỉnh sửa chuỗi kết nối để khớp với thông tin đăng nhập cơ sở dữ liệu cục bộ của bạn.

Thư mục dự án của bạn bây giờ sẽ giống như sau:

./
│
├── src/
│   └── lib.rs
│
├── .env
├── .gitignore
└── Cargo.toml

Bây giờ hãy chạy lệnh sau:

diesel setup

Lệnh này sẽ giúp chúng ta thiết lập cơ sở dữ liệu và tạo một thư mục di chuyển trống để quản lý lược đồ cơ sở dữ liệu.

Thiết lập di chuyển Diesel

Di chuyển giúp ORM theo dõi các hoạt động của cơ sở dữ liệu, chẳng hạn như thêm trường hoặc xóa bảng. Bạn có thể coi chúng như một hệ thống kiểm soát phiên bản cho cơ sở dữ liệu của mình.

Đầu tiên, hãy tạo một số chuyển đổi cho ứng dụng lớp học bằng Diesel CLI. Tốt nhất, chúng ta nên có một bảng chứa dữ liệu về học sinh trong lớp.
Chúng ta cần tạo các tệp di chuyển trống, sau đó điền chúng bằng SQL để tạo bảng.

diesel migration generate create_students

Cây tệp của bạn sẽ trông giống như sau:

./
│
├── migrations/
│   │
│   ├── 2022-07-04-062521_create_students/
│   │   ├── down.sql
│   │   └── up.sql
│   │
│   └── .gitkeep
│
├── src/
│   └── lib.rs
│
├── .env
├── .gitignore
├── Cargo.toml
└── diesel.toml

Tệp up.sqllà để tạo quá trình di chuyển, trong khi down.sqltệp dùng để đảo ngược nó.

Cập nhật up.sqltệp bằng SQL để di chuyển:

sql
CREATE TABLE students (
  id INTEGER AUTO_INCREMENT PRIMARY KEY,
  firstname VARCHAR(255) NOT NULL,
  lastname TEXT NOT NULL,
  age INTEGER NOT NULL
);

Sửa đổi down.sqltệp bằng SQL có thể đảo ngược quá trình di chuyển:

sql
DROP TABLE students;

Sau khi tạo updowndi chuyển, chúng ta cần thực thi SQL trên cơ sở dữ liệu:

diesel migration run

Chúng ta có thể bắt đầu viết Rust để thực hiện các truy vấn trên bảng.

Tạo hàng bằng Diesel ORM

Hãy viết mã để thiết lập kết nối đến máy chủ MySQL bằng cách sử dụng chuỗi kết nối được đặt trong .envtệp.

#[macro_use]
extern crate diesel;
extern crate dotenv;

pub mod models;
pub mod schema;

use diesel::prelude::*;
use dotenv::dotenv;
use std::env;

pub fn create_connection() -> MysqlConnection {
    dotenv().ok();

    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
    MysqlConnection::establish(&database_url)
        .unwrap_or_else(|_| panic!("Error connecting to {}", database_url))
}

Tiếp theo, chúng ta phải viết một mô hình cho Studentsbảng. Mô hình là nơi diễn ra ánh xạ quan hệ đối tượng. Mô hình sẽ tạo ra mã cần thiết để chuyển đổi một hàng hoặc các hàng trên Studentsbảng thành một Student cấu trúc trong Rust .

cd ./src
touch model.rs

Trong model.rstệp mới mà chúng tôi vừa tạo, hãy thêm thông tin sau:

use super::schema::students;

#[derive(Queryable)]
pub struct Student {
    pub id: i32,
    pub firstname: String,
    pub lastname: String,
    pub age: i32,
}

#[derive(Insertable)]
#[table_name = "students"]
pub struct NewStudent<'a> {
    pub firstname: &'a str,
    pub lastname: &'a str,
    pub age: &'a i32,
}

Với mô hình này, thông tin từ Studentsbảng sẽ ánh xạ tới Studentcấu trúc tương ứng trong Rust. Thư srcmục bây giờ sẽ trông như thế này:

src/
├── lib.rs
├── models.rs
└── schema.rs

Bây giờ, chúng ta có thể viết một tập lệnh để thêm một sinh viên:

cd src mkdir bin cd bin touch create_students.rs

Trong create_students.rstệp, chúng ta có thể gọi các mô hình và hàm đã viết trước đó để tạo một sinh viên mới:

extern crate classroom_diesel;
extern crate diesel;

use self::classroom_diesel::*;
fn main() {
    let connection = create_connection();
    let firstname = "John";
    let lastname = "Doe";
    let age: i32 = 64;

    let student = create_post(&connection, firstname, lastname, &age);
    println!(
        "Saved student {} with id {}",
        student.firstname, student.id
    );
}

Cấu trúc của dự án bây giờ sẽ giống như sau:

./
│
├── migrations/
│   │
│   ├── 2022-07-04-062521_create_students/
│   │   ├── down.sql
│   │   └── up.sql
│   │
│   └── .gitkeep
│
├── src/
│   │
│   ├── bin/
│   │   └── create_students.rs
│   │
│   ├── lib.rs
│   ├── models.rs
│   └── schema.rs
│
├── .env
├── .gitignore
├── Cargo.lock
├── Cargo.toml
└── diesel.toml

Thực thi tập lệnh mới bằng lệnh sau:

cargo run --bin create_students

Như bạn có thể thấy trong hình ảnh bên dưới, tệp sinh viên mới cho Johnđã được lưu idvới 1. Chúng ta có thể sử dụng điều này idđể truy vấn cơ sở dữ liệu Rust, chúng ta sẽ xem xét trong phần tiếp theo.

Kết quả ánh xạ bảng sinh viên thành một cấu trúc để tạo tệp sinh viên mới trong Diesel ORM

Truy vấn cơ sở dữ liệu gỉ với Diesel ORM

Trong phần trước, chúng ta đã xem xét cách ghi vào cơ sở dữ liệu trong Rust bằng Diesel ORM. Nó cũng rất cần thiết để hiểu cách hoạt động của truy vấn hoặc đọc.

Hãy viết một kịch bản để truy vấn một sinh viên id1. Bắt đầu bằng cách tạo một query_students.rstệp:

cd bin
touch query_students.rs

Sau đó, trong query_students.rstệp chúng tôi vừa tạo, thêm thông tin sau:

extern crate classroom_diesel;
extern crate diesel;

use self::models::*;
use classroom_diesel::*;
use diesel::prelude::*;

fn main() {
    use self::schema::students::dsl::*;

    let connection = create_connection();
    let result = students
        .filter(id.eq(1))
        .load::<Student>(&connection)
        .expect("Error loading students");

    println!(
        "Student: {} {} {} years",
        result[0].firstname, result[0].lastname, result[0].age
    );
}

Thực thi tập lệnh:

cargo run --bin query_students

Như bạn có thể thấy trong hình dưới đây, kết quả là một dòng in chứa tên, họ và tuổi của tệp sinh viên mà chúng tôi đã truy vấn từ cơ sở dữ liệu:

Kết quả Truy vấn Tệp Sinh viên Từ Cơ sở dữ liệu Rust bằng Diesel ORM

Bắt đầu với SQLx

Bây giờ chúng ta đã biết cách tạo một dự án sử dụng Diesel ORM để tương tác với cơ sở dữ liệu trong Rust, chúng ta hãy xem cách tạo một dự án sử dụng SQLx.

Khởi tạo một dự án mới với SQLx

Bắt đầu bằng cách chạy lệnh dưới đây:

cargo new classroom_sqlx --bin

Sau đó, thêm các phụ thuộc bắt buộc vào cargo.tomltệp:

[dependencies]
sqlx = { version = "0.5", features = [  "runtime-async-std-native-tls", "mysql" ] }
async-std = { version = "1", features = [ "attributes" ] }

Đó là tất cả những gì bạn cần liên quan đến việc thiết lập. Đơn giản, phải không?

Để sử dụng SQLx để tương tác với cơ sở dữ liệu trong Rust, tất cả những gì chúng ta phải làm là viết một số truy vấn SQL và mã Rust. Trong phần Diesel ORM, chúng tôi đã tạo và đọc hồ sơ học sinh; trong phần này, chúng tôi sẽ viết các truy vấn để cập nhật và xóa một bản ghi.

Sử dụng SQLx và Rust để cập nhật hoặc xóa bản ghi cơ sở dữ liệu

Đầu tiên, chúng ta cần viết một số mã Rust để kết nối SQLx với máy chủ MySQL:

//main.rs

use sqlx::mysql::MySqlPoolOptions;

#[async_std::main]
async fn main() -> Result<(), sqlx::Error> {
    let pool = MySqlPoolOptions::new()
        .max_connections(7)
        .connect("mysql://root:@localhost/classroom_diesel")
        .await?;

    Ok(())
}

SQLx hỗ trợ cả truy vấn SQL chuẩn bị và chưa chuẩn bị. Các truy vấn SQL chuẩn bị không thích với SQL injection.

Hãy xem cách cập nhật họ và tên của bản ghi có khóa chính là 1:

use sqlx::mysql::MySqlPoolOptions;

#[async_std::main]
async fn main() -> Result<(), sqlx::Error> {
    let pool = MySqlPoolOptions::new()
        .max_connections(5)
        .connect("mysql://root:@localhost/classroom_diesel")
        .await?;

    sqlx::query("UPDATE students SET firstname=?, lastname=? WHERE id=?")
        .bind("Richard")
        .bind("Roe")
        .bind(1)
        .execute(&pool)
        .await?;
    Ok(())
}

Thực thi tập lệnh bằng lệnh dưới đây:

cargo run

Xóa bản ghi cũng có một mô hình tương tự; sự khác biệt duy nhất là truy vấn SQL:

use sqlx::mysql::MySqlPoolOptions;

#[async_std::main]
async fn main() -> Result<(), sqlx::Error> {
    let pool = MySqlPoolOptions::new()
        .max_connections(5)
        .connect("mysql://root:@localhost/classroom_diesel")
        .await?;

    sqlx::query("DELETE FROM students WHERE id=?")
        .bind(1)
        .execute(&pool)
        .await?;
    Ok(())
}

Thực thi tập lệnh bằng lệnh dưới đây:

cargo run

Giờ đây, bạn có thể tương tác với cơ sở dữ liệu trong Rust bằng cách sử dụng Diesel hoặc SQLx.

Sự kết luận

ORM như Diesel là phù hợp; chúng giúp bạn tạo ra một số SQL mà bạn cần. Hầu hết thời gian, đầy đủ là tất cả những gì bạn cần trong các ứng dụng của mình.

Tuy nhiên, có thể cần nhiều “ma thuật” hơn - nói cách khác là thời gian và nỗ lực của bạn - trong các ứng dụng mở rộng hơn để các ORM hoạt động chính xác và tạo ra các truy vấn SQL hiệu quả.

Nếu phát sinh nhu cầu tạo các truy vấn phức tạp hơn với yêu cầu về khối lượng lớn và độ trễ thấp, có thể tốt hơn là sử dụng các thư viện như SQLx để thực thi các truy vấn SQL thô.

Nguồn: https://blog.logrocket.com/interactive-databases-rust-diesel-vs-sqlx/

  #rust #database 

Tương Tác Với Cơ Sở Dữ Liệu Trong Rust Bằng Diesel So Với SQLx
Dexter  Goodwin

Dexter Goodwin

1660450140

Realtime Database Backend Based on Operational Transformation (OT)

ShareDB

ShareDB is a realtime database backend based on Operational Transformation (OT) of JSON documents. It is the realtime backend for the DerbyJS web application framework.

For help, questions, discussion and announcements, join the ShareJS mailing list or read the documentation.

Please report any bugs you find to the issue tracker.

Features

  • Realtime synchronization of any JSON document
  • Concurrent multi-user collaboration
  • Synchronous editing API with asynchronous eventual consistency
  • Realtime query subscriptions
  • Simple integration with any database
  • Horizontally scalable with pub/sub integration
  • Projections to select desired fields from documents and operations
  • Middleware for implementing access control and custom extensions
  • Ideal for use in browsers or on the server
  • Offline change syncing upon reconnection
  • In-memory implementations of database and pub/sub for unit testing
  • Access to historic document versions
  • Realtime user presence syncing

Examples

Counter

demo.gif

Leaderboard

demo.gif

Development

Documentation

The documentation is stored as Markdown files, but sometimes it can be useful to run these locally. The docs are served using Jekyll, and require Ruby >2.4.0 and Bundler:

gem install jekyll bundler

The docs can be built locally and served with live reload:

npm run docs:install
npm run docs:start

Documentation

https://share.github.io/sharedb/

Download Details:

Author: Share
Source Code: https://github.com/share/sharedb 
License: View license

#javascript #database #transform 

Realtime Database Backend Based on Operational Transformation (OT)

Interacting with Databases in Rust using Diesel vs. SQLx

In this tutorial, we’ll explore two libraries used when interacting with relational databases in Rust: Diesel and SQLx.

This article will use a simple classroom database with students to demonstrate each approach. We’ll perform CRUD operations using Diesel ORM and SQLx.

See more at: https://blog.logrocket.com/interacting-databases-rust-diesel-vs-sqlx/

#rust #database 

Interacting with Databases in Rust using Diesel vs. SQLx

StringDB: A Modular, Key/value Pair Archival DB built on C#

StringDB

Install-Package StringDB

Introduction

StringDB is a key/value pair store with a friendly API to use as little RAM and space as possible.

Verify the claims for yourself:

Api

Enumerate over a database and it's values, the fastest, by enumerating over it optimally

using var db = new DatabaseBuilder()
    .UseIODatabase(StringDBVersion.Latest, "database.db", out var optimalTokenSource)
    .WithBuffer(1000)
    .WithTranform(StringTransformation.Default, StringTransformation.Default);
    
foreach (var (key, value) in db.EnumerateOptimally(optimalTokenSource))
{
    // do something with the key and value
}

Use fluent extensions to create a database:

using IDatabase<string, string> db = new DatabaseBuilder()
    .UseIODatabase(StringDBVersion.Latest, "database.db")
    .WithBuffer(1000)
    .WithTransform(StringTransformation.Default, StringTransformation.Default);

using IDatabase<int, string> memDb = new DatabaseBuilder()
    .UseMemoryDatabase<int, string>();

Use the IDatabase interface to interface with databases

void InsertGreeting(IDatabase<string, string> database, string user)
{
    database.Insert(user, $"Greetings, {user}!");
}

And inherit BaseDatabase to create your own IDatabases with minimal effort

public class TestDatabase : BaseDatabase<int, string>
{
    private class LazyValue : ILazyLoader<string>
    {
        private readonly string _value;
        public LazyValue(int value) => _value = value.ToString();
        public string Load() => _value;
        public void Dispose() {}
    }
    
    public override void Dispose() {}

    protected override void InsertRange(KeyValuePair<int, string>[] items)
    {
        foreach(var item in items)
        {
            Console.WriteLine($"{item.Key}: {item.Value}");
        }
    }

    protected override IEnumerable<KeyValuePair<int, ILazyLoader<string>>> Evaluate()
    {
        for(var i = 0; i < int.MaxValue)
        {
            yield return KeyValuePair.Create(i, new LazyValue(i));
        }
    }
}

Tiny 

StringDB is tiny. Use tiny amounts of RAM, and tiny amounts of space.

StringDB 10.0.0 file size: single inserts, 128 byte keys, 1024 byte values

Chart

InsertsSize (in KB, 1000 bytes)Absolute Minimum Size PossibleStringDB Overhead Percentage
11.172 KB1.152 KB1.706485%
5058.208 KB57.6 KB1.04453%
100116.408 KB115.2 KB1.037729%

This chart shows the size of a StringDB file after multiple single inserts. Every key is 128 bytes long, and every value is 1024 bytes long. By doing single inserts, file size is dramatically affected due to the additional overhead for the index chain.

StringDB 10.0.0 file size: insert range, 128 byte keys, 1024 byte values

Chart

Elements in Insert RangeSize (in KB, 1000 bytes)Absolute Minimum Size PossibleStringDB Overhead Percentage
11.172 KB1.152 KB1.706485%
5057.963 KB57.6 KB0.626262%
100115.913 KB115.2 KB0.615117%

This chart shows the size of a StringDB file after a single insert range with the amount of items specified.

Addons

Official addon support will be maintained for these libraries.

Issues welcomed!

Don't be afraid to make an issue about anything and everything!

  • Is there something weird with how databases are created? Submit an issue!
  • Is there something that you wish you could do but can't? Submit an issue!
  • Is this library not suitable for your purposes? Submit an isssue!
  • Want it to do something? Submit an issue!

It's an honour to have you use this library, and feedback is needed to make this the greatest it can be.

Need immediate assistence? Join the discord!

Download details:

Author: SirJosh3917
Source code: https://github.com/SirJosh3917/StringDB
License: MIT license

#dotnet #aps.net #csharp #database

StringDB: A Modular, Key/value Pair Archival DB built on C#
Nat  Grady

Nat Grady

1660331580

Rpostgis: R interface to A 'PostGIS' Database

rpostgis  

The rpostgis package provides an interface between R and PostGIS-enabled PostgreSQL databases to transparently transfer spatial data. Both vector (points, lines, polygons) and raster data are supported in read and write modes. Also provides convenience functions to execute common procedures in PostgreSQL/PostGIS.

Installation of the released versions

You can install the latest released version from CRAN:

install.packages("rpostgis")

You can then use update.packages() to update to the latest CRAN version.

Installation of the development versions

A stable version of the package is always available on the project's GitHub page, and may be ahead of the CRAN version. To install it, use the remotes:

remotes::install_github("mablab/rpostgis")

For the latest (possibly unstable) development version, use:

remotes::install_github("mablab/rpostgis", ref = "dev")

Getting started

rpostgis relies on a working connection provided by the RPostgreSQL package to a PostgreSQL database, e.g.:

conn <- RPostgreSQL::dbConnect("PostgreSQL", host = "localhost",
    dbname = "<DB_NAME>", user = "<USER>", password = "<PASSWORD>")

Note: as of rpostgis 1.4.3 the RPostgres::Postgres() driver is also allowed for connection objects; however, this should be considered experimental and is not recommended for most use cases.

Once the connection is established, the first step is to check if the database has PostGIS already installed (and install it if it's not the case):

pgPostGIS(conn)

If the function returns TRUE, the database is ready and functional. You can check the geometries and rasters present in the database with:

pgListGeom(conn, geog = TRUE)
pgListRast(conn)

To terminate the session, close and clear the connection with:

RPostgreSQL::dbDisconnect(conn)

Documentation

Full documentation with the complete list of functions of the package can be found on rpostgis homepage.

Download Details:

Author: mablab
Source Code: https://github.com/mablab/rpostgis 

#r #postgresql #database 

Rpostgis: R interface to A 'PostGIS' Database

Marten: .NET Transactional Document DB and Event Store on PostgreSQL

Marten

.NET Transactional Document DB and Event Store on PostgreSQL

The Marten library provides .NET developers with the ability to use the proven PostgreSQL database engine and its fantastic JSON support as a fully fledged document database. The Marten team believes that a document database has far reaching benefits for developer productivity over relational databases with or without an ORM tool.

Marten also provides .NET developers with an ACID-compliant event store with user-defined projections against event streams.

Access docs here and v3.x docs here.

Working with the Code

Before getting started you will need the following in your environment:

1. .NET Core SDK 5.0+ and the .NET Core 3.1 Runtime

Available here

2. PostgreSQL 9.6 or above database with PLV8

The fastest possible way to develop with Marten is to run PostgreSQL in a Docker container. Assuming that you have Docker running on your local box, type dotnet run --framework net6.0 -- init-db at the command line to spin up a Postgresql database with PLv8 enabled and configured in the database. The default Marten test configuration tries to find this database if no PostgreSQL database connection string is explicitly configured following the steps below:

You need to enable the PLV8 extension inside of PostgreSQL for running JavaScript stored procedures for the nascent projection support.

Ensure the following:

  • The login you are using to connect to your database is a member of the postgres role
  • An environment variable of marten_testing_database is set to the connection string for the database you want to use as a testbed. (See the Npgsql documentation for more information about PostgreSQL connection strings ).

Help with PSQL/PLV8

  • On Windows, see this link for pre-built binaries of PLV8
  • On *nix, check marten-local-db for a Docker based PostgreSQL instance including PLV8.

Once you have the codebase and the connection string file, run the build command or use the dotnet CLI to restore and build the solution.

You are now ready to contribute to Marten.

See more in Contribution Guidelines.

Tooling

Build Commands

DescriptionWindows CommandlinePowerShellLinux ShellDotNet CLI
Run restore, build and testbuild.cmdbuild.ps1build.shdotnet build src\Marten.sln
Run all tests including mocha testsbuild.cmd testbuild.ps1 testbuild.sh testdotnet run -p build/build.csproj -- test
Run just mocha testsbuild.cmd mochabuild.ps1 mochabuild.sh mochadotnet run -p build/build.csproj -- mocha
Run StoryTeller testsbuild.cmd storytellerbuild.ps1 storytellerbuild.sh storytellerdotnet run -p build/build.csproj -- storyteller
Open StoryTeller editorbuild.cmd open_stbuild.ps1 open_stbuild.sh open_stdotnet run -p build/build.csproj -- open_st
Run docs website locallybuild.cmd docsbuild.ps1 docsbuild.ps1 docsdotnet run -p build/build.csproj -- docs
Publish docsbuild.cmd publish-docsbuild.ps1 publish-docsbuild.sh publish-docsdotnet run -p build/build.csproj -- publish-docs
Run benchmarksbuild.cmd benchmarksbuild.ps1 benchmarksbuild.sh benchmarksdotnet run -p build/build.csproj -- benchmarks

Note: You should have a running Postgres instance while running unit tests or StoryTeller tests.

xUnit.Net Specs

The tests for the main library are now broken into three testing projects:

  1. CoreTests -- basic services like retries, schema management basics
  2. DocumentDbTests -- anything specific to the document database features of Marten
  3. EventSourcingTests -- anything specific to the event sourcing features of Marten

To aid in integration testing, Marten.Testing has a couple reusable base classes that can be use to make integration testing through Postgresql be more efficient and allow the xUnit.Net tests to run in parallel for better throughput.

  • IntegrationContext -- if most of the tests will use an out of the box configuration (i.e., no fluent interface configuration of any document types), use this base type. Warning though, this context type will not clean out the main public database schema between runs, but will delete any existing data
  • DestructiveIntegrationContext -- similar to IntegrationContext, but will wipe out any and all Postgresql schema objects in the public schema between tests. Use this sparingly please.
  • OneOffConfigurationsContext -- if a test suite will need to frequently re-configure the DocumentStore, this context is appropriate. You do not need to decorate any of these test classes with the [Collection] attribute. This fixture will use an isolated schema using the name of the test fixture type as the schema name
  • BugIntegrationContext -- the test harnesses for bugs tend to require custom DocumentStore configuration, and this context is a specialization of OneOffConfigurationsContext for the bugs schema.
  • StoreFixture and StoreContext are helpful if a series of tests use the same custom DocumentStore configuration. You'd need to write a subclass of StoreFixture, then use StoreContext<YourNewStoreFixture> as the base class to share the DocumentStore between test runs with xUnit.Net's shared context (IClassFixture<T>)

Mocha Specs

Refer to the build commands section to look up the commands to run Mocha tests. There is also npm run tdd to run the mocha specifications in a watched mode with growl turned on.

Note: remember to run npm install

Storyteller Specs

Refer to build commands section to look up the commands to open the StoryTeller editor or run the StoryTeller specs.

Documentation

All the documentation is written in Markdown and the docs are published as a static site hosted in Netlify. v4.x and v3.x use different documentation tools hence are detailed below in separate sub-sections.

v4.x and above

VitePress is used as documentation tool. Along with this, MarkdownSnippets is used for adding code snippets to docs from source code and Algolia DocSearch is used for searching the docs via the search box.

The documentation content is the Markdown files in the /docs directory directly under the project root. To run the docs locally use npm run docs with auto-refresh on any changes.

To add code samples/snippets from the tests in docs, follow the steps below:

Use C# named regions to mark a code block as described in the sample below

#region sample_my_snippet
// code sample/snippet
// ...
#endregion

All code snippet identifier starts with sample_ as a convention to clearly identify that the region block corresponds to a sample code/snippet used in docs. Recommend to use snake case for the identifiers with words in lower case.

Use the below to include the code snippet in a docs page

<!-- snippet: sample_my_snippet --> <!-- endSnippet -->

Note that when you run the docs locally, the above placeholder block in the Markdown file will get updated inline with the actual code snippet from the source code. Please commit the changes with the auto-generated inline code snippet as-is after you preview the docs page. This helps with easier change tracking when you send PR's.

Few gotchas:

  • Any changes to the code snippets will need to done in the source code. Do not edit/update any of the auto-generated inline code snippet directly in the Markdown files.
  • The latest snippet are always pulled into the docs while we publish the docs. Hence do not worry about the inline code snippet in Markdown file getting out of sync with the snippet in source code.

v3.x

stdocs is used as documentation tool. The documentation content is the markdown files in the /documentation directory directly under the project root. Any updates to v3.x docs will need to done in 3.14 branch. To run the documentation website locally with auto-refresh, refer to the build commands section above.

If you wish to insert code samples/snippet to a documentation page from the tests, wrap the code you wish to insert with // SAMPLE: name-of-sample and // ENDSAMPLE. Then to insert that code to the documentation, add <[sample:name-of-sample]>.

Note: content is published to the gh-pages branch of this repository. Refer to build commands section to lookup the command for publishing docs.

Download details:

Author: JasperFx
Source code: https://github.com/JasperFx/marten
License: MIT license

#dotnet #aps.net #csharp #database

Marten: .NET Transactional Document DB and Event Store on PostgreSQL
Hans  Marvin

Hans Marvin

1660321872

How to Manage The Filegroup Of SQL Database in SQL Server

IN this article, we are going to learn how we can manage the filegroup of SQL Database in SQL Server. The SQL Server has four filegroups.

  1. Primary Filegroup: The primary filegroup is a default filegroup. When we create a new SQL database, the Primary filegroup is automatically created.
  2. Secondary/User-defined filegroups: The secondary filegroup is created by a user. The secondary filegroup is used to manage the data of the database. If you want to keep your highly accessed tables in faster disks, you can create a secondary filegroup and a table in it.
  3. Memory-optimized filegroup: The memory-optimized filegroup is used to store the In-memory OLTP tables and table variables. To create a memory-optimized table in a SQL database, we must create a memory-optimized filegroup. We will learn more about the memory-optimized filegroups in the next article.
  4. FILESTREAM filegroup: The FILESTREAM filegroup is created to host the FILESTREAM data and FILETABLES. I will explain more about the FILESTRAEAM filegroup in the next article.

See more at: https://www.sqlshack.com/managing-file-groups-of-sql-databases/

#sql #database 

How to Manage The Filegroup Of SQL Database in SQL Server

RavenDB: An ACID NoSQL Document Database Written in C#

RavenDB

This repository contains source code for the RavenDB document database. With a RavenDB database you can set up a NoSQL data architecture or add a NoSQL layer to your current relational database.

Supported Platforms

  • Windows
  • Linux
  • Docker
  • MacOS
  • Raspberry Pi

Grab Your License and Download Latest Version

Request your license.

Download the latest version of RavenDB.

Getting Started

Install and set up your database.

Learn RavenDB Quickly

RavenDB Bootcamp is a free, self-directed learning course. In just three units you will learn how to use RavenDB to create fully-functional, real-world programs with NoSQL Databases. If you are unfamiliar with NoSQL, it’s okay. We will provide you with all the information you need.

Stay Updated on New Developments

We keep adding new features to improve your RavenDB experience. Check out our latest improvements, updated weekly.

Documentation

Access full documentation for RavenDB. Like our database, it is easy to use.

Where to Ask for Help

If you have any questions, or need further assistance, you can contact us directly.

Report an Issue

Please check where to report an issue in our contribution guidelines.

RavenDB Developer Community Group

If you have any questions please visit our discussions page or check Google community group archive. The solutions for the most common challenges are available. You are welcome to join!

Pull Requests

Please check how to submit a Pull Request in our contribution guidelines.

Setup & Run

First please review and set up prerequisites.

Launch RavenDB:

Running locally:

<path/to/ravendb>/Server/Raven.Server

Registering as service in Windows using rvn utility available in the package Server directory:

<path\to\ravendb>\rvn.exe windows-service register --service-name RavenDB4

Hello World (.NET)

Server Side

  • Launch a RavenDB server instance as follows:
<path/to/ravendb>/Server/Raven.Server --ServerUrl=http://localhost:8080

Open a web browser and enter http://localhost:8080

Click on Databases in the menu on the left-hand side, and then create a new database named SampleDataDB

Click on Settings and then on Create Sample Data in the left menu. Now Click on Create

Client Side

Install .NET Core SDK. See : Downloads and PowerShell

Open a terminal and type:

mkdir HelloWorld
cd HelloWorld
dotnet new console
  • Add the RavenDB Client package:
   dotnet add package RavenDB.Client --version 5.4.0-*
  • Replace the content of Program.cs with the following:
using System;
using Raven.Client.Documents;

namespace HelloWorld
{
    class Shippers
    {
        public string Name;
        public string Phone;
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            using (var store = new DocumentStore
            {
                Urls = new string[] {"http://localhost:8080"},
                Database = "SampleDataDB"
            })
            {
                store.Initialize();

                using (var session = store.OpenSession())
                {
                    var shipper = session.Load<Shippers>("shippers/1-A");
                    Console.WriteLine("Shipper #1 : " + shipper.Name + ", Phone: " + shipper.Phone);
                }
            }
        }
    }
}
  • Type:
dotnet restore
dotnet build
dotnet run

Enjoy :)

Download details:

Author: ravendb
Source code: https://github.com/ravendb/ravendb
License: View license

#dotnet #aps.net #csharp #database

RavenDB: An ACID NoSQL Document Database Written in C#
Thierry  Perret

Thierry Perret

1660314600

Comment Gérer Le Groupe De Fichiers De La Base De Données SQL Dans SQL

Dans cet article, nous allons apprendre comment gérer le groupe de fichiers de SQL Database dans SQL Server. Le serveur SQL a quatre groupes de fichiers.

  1. Groupe de fichiers principal : le groupe de fichiers principal est un groupe de fichiers par défaut. Lorsque nous créons une nouvelle base de données SQL, le groupe de fichiers principal est automatiquement créé.
  2. Groupes de fichiers secondaires/définis par l'utilisateur : le groupe de fichiers secondaire est créé par un utilisateur. Le groupe de fichiers secondaire est utilisé pour gérer les données de la base de données. Si vous souhaitez conserver vos tables à accès élevé sur des disques plus rapides, vous pouvez créer un groupe de fichiers secondaire et une table dans celui-ci.
  3. Groupe de fichiers à mémoire optimisée : le groupe de fichiers à mémoire optimisée est utilisé pour stocker les tables OLTP en mémoire et les variables de table. Pour créer une table optimisée en mémoire dans une base de données SQL, nous devons créer un groupe de fichiers optimisé en mémoire. Nous en apprendrons plus sur les groupes de fichiers à mémoire optimisée dans le prochain article.
  4. Groupe de fichiers FILESTREAM : le groupe de fichiers FILESTREAM est créé pour héberger les données FILESTREAM et FILETABLES. J'expliquerai plus sur le groupe de fichiers FILESTRAEAM dans le prochain article.

Le groupe de fichiers contient un ou plusieurs fichiers de données. Cet article explique comment nous pouvons gérer les Nous allons comprendre les cas d'utilisation suivants.

  1. Ajouter des fichiers de données dans des groupes de fichiers
  2. Renommer le groupe de fichiers
  3. Modifier le groupe de fichiers par défaut

Pour illustrer les scénarios ci-dessus, j'ai installé SQL Server 2019 sur mon ordinateur portable et restauré un exemple de base de données stackoverflow2010 . Vous pouvez télécharger la base de données Stackoverflow2010 à partir d' ici . J'ai également créé un groupe de fichiers nommé FG_POSTS dans une base de données. Vous pouvez afficher la liste des groupes de fichiers et la liste des groupes de fichiers associés aux fichiers de données en exécutant la requête suivante.

SELECT [databasefile].NAME      AS [FileName],
  [filegroup].NAME       AS [File_Group_Name],
  [filegroup].type_desc,
  physical_name [Data File Location],
  size / 128    AS [Size_in_MB],
  state_desc    [State of FILE],
  growth        [Data file growth]
FROM   sys.database_files [databasefile]
  INNER JOIN sys.filegroups [filegroup]
          ON [databasefile].data_space_id = [filegroup].data_space_id  

Production

Afficher la liste des groupes de fichiers de la base de données SQL

Maintenant, comprenons tous les cas d'utilisation.

Ajouter des fichiers de données dans un groupe de fichiers

Nous pouvons utiliser l'instruction ALTER DATABASE ADD FILE TO FILGRAOUP . La syntaxe est la suivante :

  ALTER DATABASE <db_name> ADD FILE (NAME= <logical_file_name>, FILENAME =<file_location>, SIZE=<File_size>, FILEGROWTH= <datafile_growth>)
  To FILEGROUP <file_group_name>

Dans la syntaxe,

  1. db_name : Spécifiez le nom de la base de données dans laquelle vous souhaitez ajouter un fichier de données. Le db_name doit être spécifié après le mot-clé ALTER DATABASE.
  2. nom_fichier_logique : spécifiez le nom logique du fichier de données secondaire.
  3. emplacement_fichier : spécifiez le chemin du fichier de données.
  4. file_size : Spécifiez la taille initiale du fichier de données. L'unité du paramètre Taille peut être Ko/Mo/Go.
  5. datafile_growth : Spécifiez la croissance du fichier de données. L'unité du paramètre FILEGROWTH peut être KB/MB/GB
  6. file_group_name : indiquez le nom du groupe de fichiers dans lequel vous souhaitez ajouter un fichier de données.

Par exemple, nous voulons ajouter un fichier de données au groupe de fichiers FG_POSTS avec les options suivantes

  1. nom de fichier logique : fg_posts_data
  2. emplacement du fichier de données : D:\FG_Posts
  3. nom_fichier_données : fg_posts_data.ndf
  4. Taille initiale : 10 Mo
  5. croissance : 5 Mo.

La requête pour ajouter un fichier de données suit.

ALTER DATABASE [Stackoverflow2010] ADD FILE ( NAME = N'fg_posts_data', FILENAME = N'D:\FG_Posts\fg_posts_data.ndf' , SIZE = 10MB , FILEGROWTH = 5MB ) 
  TO FILEGROUP [FG_POSTS]
  GO

Une fois la commande exécutée, ouvrez avec succès le D:\FG_Posts pour afficher le fichier de données.

Afficher le fichier de données secondaire

Comme vous pouvez le voir, le fichier a été créé. Vous pouvez également exécuter la requête suivante pour afficher les groupes de fichiers.

SELECT [databasefile].NAME      AS [FileName],
  [filegroup].NAME       AS [File_Group_Name],
  [filegroup].type_desc,
  physical_name [Data File Location],
  size / 128    AS [Size_in_MB],
  state_desc    [State of FILE],
  growth        [Data file growth]
FROM   sys.database_files [databasefile]
  INNER JOIN sys.filegroups [filegroup]
          ON [databasefile].data_space_id = [filegroup].data_space_id 

Sortie de la requête

Afficher le groupe de fichiers dans la base de données SQL

Comme vous pouvez le voir, le fichier de données nommé fg_posts_data a été créé.

Maintenant, comprenons comment nous pouvons renommer le groupe de fichiers existant.

Renommer le groupe de fichiers existant

Vous pouvez utiliser l'instruction ALTER DATABASE MODIFY FILEGROUP. Voici la syntaxe :

ALTER DATABASE <db_name> MODIFY FILEGROUP FILEGROUP <file_group_name> NAME= <file_group_new_name>

Dans la syntaxe,

  1. db_name : spécifiez le nom de la base de données dans laquelle le groupe de fichiers a été créé. Le nom de la base de données doit être spécifié après l'instruction ALTER DATABASE.
  2. nom_groupe_fichiers : spécifiez le nom du groupe de fichiers que vous souhaitez renommer.
  3. file_group_new_name : spécifiez le nouveau nom du groupe de fichiers.

Supposons que vous souhaitiez renommer le groupe de fichiers nommé FG_Posts en FG_POSTS_1 . La requête pour renommer le groupe de fichiers est la suivante :


 ALTER DATABASE [Stackoverflow2010] MODIFY FILEGROUP FG_POSTS NAME= FG_POSTS_1

Une fois la commande exécutée avec succès, exécutez la requête suivante pour vérifier que les modifications ont été appliquées ou non.

Une fois la commande exécutée avec succès, exécutez la requête suivante pour vérifier que les modifications ont été appliquées ou non.

SELECT [databasefile].NAME      AS [FileName],
  [filegroup].NAME       AS [File_Group_Name],
  [filegroup].type_desc,
  physical_name [Data File Location],
  size / 128    AS [Size_in_MB],
  state_desc    [State of FILE],
  growth        [Data file growth]
FROM   sys.database_files [databasefile]
  INNER JOIN sys.filegroups [filegroup]
          ON [databasefile].data_space_id = [filegroup].data_space_id  

Production

Le groupe de fichiers a été renommé

Comme vous pouvez le voir, le groupe de fichiers a été renommé avec succès.

Voyons maintenant comment marquer un groupe de fichiers secondaire comme groupe de fichiers par défaut.

Modifier le groupe de fichiers par défaut

Pour changer le groupe de fichiers par défaut, nous pouvons utiliser l'instruction ALTER DATABASE MODIFY FILEGROUP. Voici la syntaxe :

ALTER DATABASE <db_name> MODIFY FILEGROUP <file_group_name> DEFAULT

Dans la syntaxe,

  1. db_name : spécifiez le nom de la base de données dans laquelle le groupe de fichiers a été créé. Le nom de la base de données doit être spécifié après l'instruction ALTER DATABASE.
  2. File_group_name : spécifiez le nom du groupe de fichiers que vous souhaitez définir comme groupe de fichiers par défaut. Le nom du groupe de fichiers doit être spécifié après le mot-clé MODIFY FILEGROUP.
  3. DEFAULT : le mot-clé DEFAULT doit être spécifié après le nom du groupe de fichiers.

Supposons que vous souhaitiez définir FG_POSTS_1 comme groupe de fichiers par défaut. Pour ce faire, exécutez la requête suivante.

 ALTER DATABASE [Stackoverflow2010] MODIFY FILEGROUP [FG_POSTS_1] DEFAULT

Une fois la commande exécutée avec succès, exécutez la requête suivante pour afficher le groupe de fichiers par défaut d'une base de données nommée Stackoverflow2010 .

SELECT [databasefile].NAME      AS [FileName],
  [filegroup].NAME       AS [File_Group_Name],
  [filegroup].type_desc,
  physical_name [Data File Location],
Case when is_default =1 then 'Default filegroup' else 'non-default filegroup' end [Is default Filegroup],
  size / 128    AS [Size_in_MB],
  state_desc    [State of FILE],
  growth        [Data file growth]
FROM   sys.database_files [databasefile]
  INNER JOIN sys.filegroups [filegroup]
          ON [databasefile].data_space_id = [filegroup].data_space_id  

Sortie de la requête

Afficher le groupe de fichiers par défaut

Comme vous pouvez le voir, le FG_POSTS_1 est un groupe de fichiers par défaut.

Maintenant, créons une table nommée tblStackoverflow_Users. Le script pour créer la table est le suivant :

 USE [Stackoverflow2010]
  GO
  CREATE TABLE [dbo].[tblStackoverflow_Users](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [AboutMe] [nvarchar](max) NULL,
    [Age] [int] NULL,
    [CreationDate] [datetime] NOT NULL,
    [DisplayName] [nvarchar](40) NOT NULL,
    [DownVotes] [int] NOT NULL,
    [EmailHash] [nvarchar](40) NULL,
    [LastAccessDate] [datetime] NOT NULL,
    [Location] [nvarchar](100) NULL
   CONSTRAINT [PK_tblStackoverflow_Users_Id] PRIMARY KEY CLUSTERED 
  (
    [Id] ASC
  ))
  GO

Voyons maintenant dans quel groupe de fichiers la table a été créée. Pour ce faire, exécutez la requête suivante :

use Stackoverflow2010
  go
  SELECT OBJECT_NAME(t.object_id) AS [Table Name], d.name AS [Filegroup Name]  FROM sys.data_spaces d 
  JOIN sys.indexes i on i.data_space_id = d.data_space_id
  JOIN sys.tables t on t.object_id = i.object_id
  WHERE i.index_id<2
  AND t.type = 'U'
  AND OBJECT_NAME(t.object_id) ='tblStackoverflow_Users'

Production

Nom du groupe de fichiers de la base de données SQL

Comme vous pouvez le voir, la table est créée dans le groupe de fichiers FG_POSTS_1 .

Sommaire

Dans cet article, nous avons appris comment gérer les groupes de fichiers dans SQL Database. Nous avons appris les scénarios suivants :

  1. Ajouter des fichiers de données dans des groupes de fichiers
  2. Renommer le groupe de fichiers
  3. Modifier le groupe de fichiers par défaut

Lien : https://www.sqlshack.com/managing-file-groups-of-sql-databases/

#sql #database

Comment Gérer Le Groupe De Fichiers De La Base De Données SQL Dans SQL