rust 在sqlx中创建和迁移数据库

jslywgbw  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(174)

我正在阅读从零到生产的书,书的第74-76页谈到了测试函数在运行多次时如何失败,因为每次我们运行cargo test测试函数都会运行应用程序,并且应用程序中有一个插入查询,所以每次我们运行测试时,调用该应用程序,执行插入查询,并插入相同的值,这由于唯一键约束而导致错误。本书提供了一个解决方案
1.创建具有唯一名称的新逻辑数据库
2.run迁移到此数据库

//! tests/health_check.rs
use std::net::TcpListener;
use sqlx::{PgConnection, PgPool, Connection, Executor};
use zero2prod::configuration::{get_configuration, DatabaseSettings};
use zero2prod::startup::run;
use uuid::Uuid;

pub struct TestApp {
    pub address: String,
    pub pool: PgPool,
}

async fn spawn_app() -> TestApp {
    let listener = TcpListener::bind("127.0.0.1:0").expect("failed to bind to the port");
    let port = listener.local_addr().unwrap().port();
    let address = format!("http://127.0.0.1:{}", port);

    let mut configuration = get_configuration().expect("failed to read configuration");
    configuration.database.database_name = Uuid::new_v4().to_string();
    let connection_pool = PgPool::connect(&configuration.database.connection_string()).await.expect("failed to connect to postgres");
    let server = run(listener, connection_pool.clone()).expect("failed to bind to address");
    let _ = tokio::spawn(server);
    TestApp{
        address,
        pool: connection_pool,
    }
}

字符串
本书随后进行了以下修改:

//! tests/health_check.rs
let mut configuration = get_configuration().expect("Failed to read configuration.");
configuration.database.database_name = Uuid::new_v4().to_string();
let connection_pool = PgPool::connect(&configuration.database.connection_string())
.await
.expect("Failed to connect to Postgres.");

x

//! src/configuration.rs
// [...]
impl DatabaseSettings {
pub fn connection_string(&self) -> String {
    format!(
        "postgres://{}:{}@{}:{}/{}",
        self.username, self.password, self.host, self.port, self.database_name
    )

}
    pub fn connection_string_without_db(&self) -> String {
        format!(
            "postgres://{}:{}@{}:{}",
            self.username, self.password, self.host, self.port
        )
    }
}
//! tests/health_check.rs
// [...]
use sqlx::{Connection, Executor, PgConnection, PgPool};
use zero2prod::configuration::{get_configuration, DatabaseSettings};
async fn spawn_app() -> TestApp {
// [...]
let mut configuration = get_configuration().expect("Failed to read configuration.");
configuration.database.database_name = Uuid::new_v4().to_string();
let connection_pool = configure_database(&configuration.database).await;
// [...]
}
pub async fn configure_database(config: &DatabaseSettings) -> PgPool {
// Create database
    let mut connection = PgConnection::connect(&config.connection_string_without_db())
        .await
        .expect("Failed to connect to Postgres");
    connection
        .execute(format!(r#"CREATE DATABASE "{}";"#, config.database_name).as_str())
        .await
        .expect("Failed to create database.");
// Migrate database
    let connection_pool = PgPool::connect(&config.connection_string())
        .await
        .expect("Failed to connect to Postgres.");
    sqlx::migrate!("./migrations")
        .run(&connection_pool)
        .await
        .expect("Failed to migrate the database");
    connection_pool
}

的字符串
我不明白最后一个函数configure_database的作用,以及添加该函数如何解决问题

u3r8eeie

u3r8eeie1#

如果他不创建一个新的数据库,并使用相同的数据库,他将无法做全面的测试,因为他们的数据是从以前的测试。我也读过这本书,他正在使用Docker容器来实现Postgress。而不是创建一个新的随机数据库,他也可以删除docker容器并创建一个新的,每次他运行测试时,他可以使用常量数据库名称。如果你问我的话,这是个让人头疼的过程

相关问题