How to store a Vapor Fluent model with decimal field

473 views Asked by At

I have a Fluent (Postgres backed) model that requires type Decimal, but I'm only allowed to store .float/.double.

// Model
final class Stat: Model, Content, Equatable {
    static let schema: String = "stats"
    
    @ID(key: .id)
    var id: UUID?
    
    @Field(key: "name")
    var name: String

    @Field(key: "earned_run_average")
    var era: Decimal // <-- CAN'T DO THIS
}
// Migration
struct CreateStatsTable: Migration {
    func prepare(on database: Database) -> EventLoopFuture<Void> {
        return database.schema(Stats.schema)
            .id()
            .field("name", .string, .required)
            .field("earned_run_average", .decimal/*.decimal TYPE DOES NOT EXIST */, .required)
            .create()
    }

    func revert(on database: Database) -> EventLoopFuture<Void> {
        return database.schema(Stats.schema).delete()
    }
}

The above model with migration will fail. If this is not easily achievable (as easy as .string or .double) is there a way to get a behavior similar to type Decimal in Fluent?

1

There are 1 answers

0
Jawad On

Proper Decimal support for Postgres was added recently.

So you should be able to use Decimal in the Model for encoding/decoding to and from a Decimal value in the Postgres DB without any issues.

As for the Migration, there still isn't a .decimal DataType so you can simply use a custom field for the Postgres Database like numeric as so:

.field("earned_run_average", .sql(raw: "NUMERIC(7,2)"), .required)

This should allow you to use Decimal without any issues.