fluent-kit icon indicating copy to clipboard operation
fluent-kit copied to clipboard

UUID field backed by String column in Postgres breaks `filter`

Open eob opened this issue 3 years ago • 1 comments

Describe the bug

I'm using UUIDs for primary keys in my Fluent model representation, like this:

  @ID public var id: UUID?
  @OptionalField(key: .userId) public var userId: UUID?

Backed by string columns in Postgres, like this:

      .field(FieldKey("id"), .string, .identifier(auto: false))
      .field(.userId, .string)

When I attempt to perform a filter operation with QueryBuilder like this:

     .filter(\.$userId == someOtherId)

I get the following error: Optional(server: operator does not exist: text = uuid (op_error))

If filtering records in a SELECT query, this alternative method of invoking filter will avoid the error:

      .filter(.userId, .equal, userId.uuidString.lowercased())

But sometimes this bug is unavoidable: the more compact filter invocation is prevalent inside FluentKit. For example, model.update performs the following filter:

    .filter(\._$id == self.id!)

Is there some workaround that I can use to update my models? I'd prefer to keep the column type text in the database if at all possible.

Thanks for the help! This project is fantastic and I'm really appreciative of all the amazing work on it.

To Reproduce

Steps to reproduce the behavior:

  1. Add package with configuration '...'
  2. Send request with options '...'
  3. See error

Expected behavior

A clear and concise description of what you expected to happen.

Environment

  • Vapor Framework version:
  • Vapor Toolbox version:
  • OS version:

Additional context

Add any other context about the problem here.

eob avatar Apr 23 '21 04:04 eob

No there is no way around this. Why do you want to keep them as text? Postgres has a native UUID type so that's what Fluent uses. Unfortunately trying to convert that to a string inside Fluent would break too many things.

You might be able to work around this by setting the ID types to Strings instead of UUIDs and converting from UUID to String before you set it in the model

0xTim avatar Apr 23 '21 09:04 0xTim