Skip to content

PgVector mis-mapped in codegen #2586

@cimandef

Description

@cimandef

Description

Hello, thank you for this wonderful integration with pgvector! Unfortunately, I've been encountering unexpected behavior while generating entities from a migration that integrates a vector.

Steps to Reproduce

  1. Write a migration like this:
use sea_orm::{sea_query::extension::postgres::Extension, TransactionTrait};
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> {
        let tx = manager.get_connection().begin().await?;

        tx.execute(sea_orm::Statement::from_string(
            manager.get_database_backend(),
            Extension::create()
                .name("vector")
                .cascade()
                .if_not_exists()
                .to_string(PostgresQueryBuilder),
        ))
        .await?;

        manager
            .create_table(
                Table::create()
                    .table(Search::Table)
                    .col(
                        ColumnDef::new(Search::Id)
                            .integer()
                            .not_null()
                            .primary_key()
                            .auto_increment(),
                    )
                    .col(ColumnDef::new(Search::Content).string().not_null())
                    .col(ColumnDef::new(Search::Vector).vector(None).not_null())
                    .to_owned(),
            )
            .await?;

        tx.commit().await?;

        Ok(())
    }

    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
        let tx = manager.get_connection().begin().await?;

        tx.execute(sea_orm::Statement::from_string(
            manager.get_database_backend(),
            Extension::drop()
                .name("vector")
                .cascade()
                .to_string(PostgresQueryBuilder),
        ))
        .await?;

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

        tx.commit().await?;

        Ok(())
    }
}

#[derive(DeriveIden)]
enum Search {
    Table,
    Id,
    Content,
    Vector,
}
  1. Install the latest version of sea-orm-cli with the pg-vector flag:
    cargo install sea-orm-cli --features=postgres-vector --locked --force
  2. Then generate the entities with:
    sea generate entity -o entity/src/generated

Expected Behavior

We should get this generated entity:

//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.10

use sea_orm::entity::prelude::*;

#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
#[sea_orm(table_name = "search")]
pub struct Model {
    #[sea_orm(primary_key)]
    pub id: i32,
    pub content: String,
    pub vector: PgVector,
}

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

impl ActiveModelBehavior for ActiveModel {}

Actual Behavior

But we get:

//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.10

use sea_orm::entity::prelude::*;

#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "search")]
pub struct Model {
    #[sea_orm(primary_key)]
    pub id: i32,
    pub content: String,
    #[sea_orm(column_type = "custom(\"vector\")")]
    pub vector: String,
}

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

impl ActiveModelBehavior for ActiveModel {}

Reproduces How Often

I can reproduce it every time, on various devices, with the latest release or the version on the main branch.

Workarounds

I've tried to debug it in this repo, and it always interprets a vector from Postgres as a custom type rather than a PgVector.

Reproducible Example

You can find an example toy app here: https://github.com/aqora-io/vector_search_playground

Versions

sea-version:

│   └── sea-orm v1.1.10
│       ├── sea-orm-macros v1.1.10 (proc-macro)
│       │   ├── sea-bae v0.2.1 (proc-macro)
│       ├── sea-query v0.32.3
│       │   ├── sea-query-derive v0.4.3 (proc-macro)
│       ├── sea-query-binder v0.7.0
│       │   ├── sea-query v0.32.3 (*)
│   ├── sea-orm v1.1.10 (*)
│   └── sea-orm-migration v1.1.10
│       ├── sea-orm v1.1.10 (*)
│       ├── sea-orm-cli v1.1.10
│       │   ├── sea-schema v0.16.1
│       │   │   ├── sea-query v0.32.3 (*)
│       │   │   └── sea-schema-derive v0.3.0 (proc-macro)
│       ├── sea-schema v0.16.1 (*)
├── sea-orm v1.1.10 (*)

Database: pgvector/pgvector:pg16 (https://hub.docker.com/layers/pgvector/pgvector/pg16/images/sha256-8fd720a9b6a49e70ca90fc0d97c2efea45c70d58b1727b92fcaecd05fcd87e40)
OS: macOS Sequoia 15.0 arm64

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions