首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >rusqlite和pyo3 PyResult处理错误

rusqlite和pyo3 PyResult处理错误
EN

Stack Overflow用户
提问于 2021-01-08 22:02:27
回答 1查看 112关注 0票数 0

在pyo3的帮助下,我正在尝试打开并写入Rust库中的数据库,我将从python调用该库。如果发生错误,我想引发一个可以在调用Python进程中捕获的异常,但我在终止执行和引发错误时遇到了困难。

代码语言:javascript
复制
use rusqlite::{Connection};
use rusqlite::NO_PARAMS;
use pyo3::{Python, wrap_pyfunction};
use pyo3::exceptions::PyIOError;

#[pyfunction]
fn do_something(_py: Python) -> PyResult<u32> {
    match Connection::open("database.sql") {
        Ok(t) => conn = t,
        Err(e) => {
            let gil = Python::acquire_gil();
            let py = gil.python();
            let error_message = format!("Unable to open database! {}", e.to_string());
            PyIOError::new_err(error_message).restore(py)
        }
    };
    
    match conn.execute(
        "create table if not exists cats (
            id              INTEGER PRIMARY KEY,
            name            TEXT NOT NULL,
        )",
        NO_PARAMS,
    ) {
        Ok(_t) => (),
        Err(e) => {
            let gil = Python::acquire_gil();
            let py = gil.python();
            let error_message = format!("Unable to open database! {}", e.to_string());
            PyIOError::new_err(error_message).restore(py)
        }
    }
    Ok(0)

我的理解是,在PyIOError对象上调用restore函数会引发错误,然而,我肯定是误解了,因为编译器似乎认为conn可能没有初始化:

代码语言:javascript
复制
error[E0381]: borrow of possibly-uninitialized variable: `conn`

18  |             match conn.execute(
    |                   ^^^^ use of possibly-uninitialized `conn`

在这里什么是合适的方法?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-08 22:36:15

首先,您的Ok(t) = conn = t会失败,因为您还没有定义conn。因此,在match之前添加let conn;。或者,您也可以只将匹配结果赋值给conn

其次,您仍然需要返回一个Err

代码语言:javascript
复制
#[pyfunction]
fn do_something(_py: Python) -> PyResult<u32> {
    let conn = match Connection::open("database.sql") {
        Ok(t) => t,
        Err(e) => {
            let gil = Python::acquire_gil();
            let py = gil.python();
            let error_message = format!("Unable to open database! {}", e.to_string());
            PyIOError::new_err(error_message).restore(py);
            return Err(PyErr::fetch(py));
        }
    };

    match conn.execute(
        "create table if not exists cats (
            id              INTEGER PRIMARY KEY,
            name            TEXT NOT NULL,
        )",
        NO_PARAMS,
    ) {
        Ok(_t) => (),
        Err(e) => {
            let gil = Python::acquire_gil();
            let py = gil.python();
            let error_message = format!("Unable to open database! {}", e.to_string());
            PyIOError::new_err(error_message).restore(py);
            return Err(PyErr::fetch(py));
        }
    }
    Ok(0)
}

我使用PyO3已经有一段时间了。但是除非我记错了,否则你可以删除restore(),也可以返回Err,让PyO3来处理剩下的事情。

代码语言:javascript
复制
#[pyfunction]
fn do_something(_py: Python) -> PyResult<u32> {
    let conn = match Connection::open("database.sql") {
        Ok(t) => t,
        Err(e) => {
            let error_message = format!("Unable to open database! {}", e.to_string());
            return Err(PyIOError::new_err(error_message));
        }
    };

    match conn.execute(
        "create table if not exists cats (
            id              INTEGER PRIMARY KEY,
            name            TEXT NOT NULL,
        )",
        NO_PARAMS,
    ) {
        Ok(_t) => (),
        Err(e) => {
            let error_message = format!("Unable to open database! {}", e.to_string());
            return Err(PyIOError::new_err(error_message));
        }
    }
    Ok(0)
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65630437

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档