查询错误:从数据库返回错误:关系“广告”不存在

问题描述 投票:0回答:1

所以我的数据库中有 2 个实体

use async_graphql::{self, SimpleObject};
use chrono::NaiveDateTime;
use sea_orm::entity::prelude::*;

#[derive(Clone, Debug, PartialEq, DeriveEntityModel, SimpleObject)]
#[sea_orm(table_name = "adverts")]
#[graphql(name = "Advert")]
pub struct Model {
    #[sea_orm(primary_key)]
    pub id: i32,
    pub created_at: NaiveDateTime,
    pub updated_at: NaiveDateTime,
    pub available: bool,
    pub price: f32,
    pub location: String,
    pub user_id: i32,
    // pub adverts
}

#[derive(Copy, Clone, Debug, EnumIter)]
pub enum Relation {
    User,
}

impl RelationTrait for Relation {
    fn def(&self) -> RelationDef {
        match self {
            Self::User => Entity::belongs_to(super::user::Entity)
                .from(Column::UserId)
                .to(super::user::Column::Id)
                .into(),
        }
    }
}

impl Related<super::user::Entity> for Entity {
    fn to() -> RelationDef {
        Relation::User.def()
    }
}

impl ActiveModelBehavior for ActiveModel {}

use async_graphql::{self, SimpleObject};
use chrono::NaiveDateTime;
use sea_orm::entity::prelude::*;

#[derive(Clone, Debug, PartialEq, DeriveEntityModel, SimpleObject)]
#[sea_orm(table_name = "user")]
#[graphql(name = "User")]
pub struct Model {
    #[sea_orm(primary_key)]
    pub id: i32,
    pub created_at: NaiveDateTime,
    pub updated_at: NaiveDateTime,
    pub name: String,
    pub surname: String,
    #[sea_orm(unique)]
    pub email: String,
    pub phone: String,
    pub balance: f32,
    #[graphql(visible = false)]
    pub password_hash: String,
    #[graphql(visible = false)]
    pub refresh_token: Option<String>,
    // pub adverts
}

#[derive(Copy, Clone, Debug, EnumIter)]
pub enum Relation {
    Advert,
}

impl RelationTrait for Relation {
    fn def(&self) -> RelationDef {
        match self {
            Self::Advert => Entity::has_many(super::advert::Entity).into(),
        }
    }
}

impl Related<super::advert::Entity> for Entity {
    fn to() -> RelationDef {
        Relation::Advert.def()
    }
}

impl ActiveModelBehavior for ActiveModel {}

impl Entity {
    pub fn find_by_email(email: String) -> Select<Entity> {
        Self::find().filter(Column::Email.eq(email))
    }
}

如您所见,我在它们之间有关系,我想提供向用户添加广告的功能,所以我编写了代码:

async fn create_advert(
        &self,
        ctx: &async_graphql::Context<'_>,
        access_token: String,
        price: f32,
        location: String,
    ) -> Result<advert::Model, async_graphql::Error> {
        let my_ctx = ctx.data::<Context>().unwrap();
        let key: Hmac<Sha256> = match Hmac::new_from_slice(b"some-secret2") {
            Ok(key) => key,
            Err(err) => return Err(async_graphql::Error::new("Wrong token".to_string())),
        };

        let claims: BTreeMap<String, String> = match access_token.verify_with_key(&key) {
            Ok(res) => res,
            Err(err) => return Err(async_graphql::Error::new("Wrong token".to_string())),
        };

        let now = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap()
            .as_secs() as usize;

        if claims["sub"] == "someone" && claims["exp"].parse::<usize>().unwrap() >= now {
            let naive_date_time = Utc::now().naive_utc();
            let advert = advert::ActiveModel {
                available: Set(true),
                user_id: Set(claims["id"].parse().unwrap()),
                created_at: Set(naive_date_time),
                updated_at: Set(naive_date_time),
                price: Set(price),
                location: Set(location),
                ..Default::default()
            };

            let advert: advert::Model = advert.insert(&my_ctx.db).await?;

            return Ok(advert);
        } else {
            return Err(async_graphql::Error::new("Wrong token".to_string()));
        }
    }

当我在 graphql 中使用我的突变时,我收到错误:查询错误:从数据库返回的错误:关系“广告”不存在

所以问题是出了什么问题?

当我为 postgresql 表打开 erd 时,我可以看到这些表之间的关系: erd

我最后一次迁移:

use sea_orm_migration::prelude::*;

#[derive(DeriveMigrationName)]
pub struct Migration;

#[async_trait::async_trait]
impl MigrationTrait for Migration {
    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
        manager
            .create_table(
                Table::create()
                    .table(User::Table)
                    .if_not_exists()
                    .col(
                        ColumnDef::new(User::Id)
                            .integer()
                            .not_null()
                            .auto_increment()
                            .primary_key(),
                    )
                    .col(ColumnDef::new(User::CreatedAt).date_time().not_null())
                    .col(ColumnDef::new(User::UpdatedAt).date_time().not_null())
                    .col(ColumnDef::new(User::Name).string().not_null())
                    .col(ColumnDef::new(User::Surname).string().not_null())
                    .col(ColumnDef::new(User::Email).string().unique_key().not_null())
                    .col(ColumnDef::new(User::Phone).string().not_null())
                    .col(ColumnDef::new(User::Balance).float().not_null())
                    .col(ColumnDef::new(User::PasswordHash).string().not_null())
                    .col(ColumnDef::new(User::RefreshToken).string())
                    .to_owned(),
            )
            .await?;
        manager
            .create_table(
                Table::create()
                    .table(Advert::Table)
                    .if_not_exists()
                    .col(
                        ColumnDef::new(Advert::Id)
                            .integer()
                            .not_null()
                            .auto_increment()
                            .primary_key(),
                    )
                    .col(ColumnDef::new(Advert::CreatedAt).date_time().not_null())
                    .col(ColumnDef::new(Advert::UpdatedAt).date_time().not_null())
                    .col(ColumnDef::new(Advert::Available).boolean().not_null())
                    .col(ColumnDef::new(Advert::Price).float().not_null())
                    .col(ColumnDef::new(Advert::Location).string().not_null())
                    .col(ColumnDef::new(Advert::UserId).integer().not_null())
                    .foreign_key(
                        ForeignKey::create()
                            .name("fk-advert-user_id")
                            .from(Advert::Table, Advert::UserId)
                            .to(User::Table, User::Id),
                    )
                    .to_owned(),
            )
            .await?;
        Ok(())
    }

    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
        manager
            .drop_table(Table::drop().table(User::Table).to_owned())
            .await?;

        manager
            .drop_table(Table::drop().table(Advert::Table).to_owned())
            .await?;

        Ok(())
    }
}

#[derive(DeriveIden)]
enum User {
    Table,
    Id,
    CreatedAt,
    UpdatedAt,
    Name,
    Surname,
    Email,
    Phone,
    Balance,
    PasswordHash,
    RefreshToken,
}

#[derive(DeriveIden)]
enum Advert {
    Table,
    Id,
    CreatedAt,
    UpdatedAt,
    Available,
    Price,
    Location,
    UserId,
}

如果是这样,我正在使用seaorm,async_graphql + actix

我期待成功使用突变

sql graphql relation sea-orm async-graphql
1个回答
0
投票

好吧,这很愚蠢,所以问题是在我的数据库中我有一个名为 advert 的表 但这里是名字广告

#[derive(Clone, Debug, PartialEq, DeriveEntityModel, SimpleObject)]
#[sea_orm(table_name = "adverts")] // here
#[graphql(name = "Advert")]
pub struct Model {
    #[sea_orm(primary_key)]
    pub id: i32,
    pub created_at: NaiveDateTime,
    pub updated_at: NaiveDateTime,
    pub available: bool,
    pub price: f32,
    pub location: String,
    pub user_id: i32,
    // pub adverts
}

因此,如果有人遇到同样的问题,解决方案是将 sea orm table_name 更改为与数据库中相同的名称

© www.soinside.com 2019 - 2024. All rights reserved.