Can anyone think of a good way to programatically ...
# orm-help
d
Can anyone think of a good way to programatically tell if a field is nullable at runtime? The data is in the schema and the types, but I need to look it up programatically at runtime, which doesn’t seem possible from what I can tell.
r
Hey @defrex 👋 Could you explain the use case for this?
d
I’m implementing Relay Connections on my graph with dynamic sort capabilities. As long as I encapsulate the
orderBy
values into the cursors this works fine. However, to calculate
hasNextPage
&
hasPreviousPage
I need to query “before” and “after” the current range for an arbitrary sort. That means something like this (for before, assuming
completedAt
is nullable)
Copy code
{
  "where": {
    "AND": [
      {
        "createdAt": {
          "lt": "2020-08-20T14:42:27.681Z"
        }
      },
      {
        "OR": [
          {
            "completedAt": {
              "gt": "2020-08-20T14:42:27.683Z"
            }
          },
          {
            "completedAt": {
              "equals": null
            }
          }
        ]
      }
    ]
  },
  "orderBy": [
    {
      "completedAt": "desc"
    },
    {
      "createdAt": "asc"
    }
  ]
}
However, that same logic applied to a non-nullable field generates this.
Copy code
{
  "where": {
    "AND": [
      {
        "completedAt": {
          "lt": "2020-08-20T14:42:27.681Z"
        }
      },
      {
        "OR": [
          {
            "createdAt": {
              "gt": "2020-08-20T14:42:27.683Z"
            }
          },
          {
            "createdAt": {
              "equals": null
            }
          }
        ]
      }
    ]
  },
  "orderBy": [
    {
      "completedAt": "asc"
    },
    {
      "createdAt": "desc"
    }
  ]
}
Which fails, since
createdAt
can’t be
null
.
All that leaves me in a place where I need to dynamically determine if a given sort key is nullable or not. Since it’s passed to me at runtime, via GraphQL, I can’t accomplish it with the type system.
FWIW, I was able to solve the problem with a database query. Though, ideally I wouldn’t have the extra IO.
Copy code
await prisma.$queryRaw`
  select
    columns.column_name,
    case columns.is_nullable
      when 'NO' then
        false
      when 'YES' then
        true
    end as nullable
  from
    information_schema.columns
  where
    columns.table_name = 'task'
`
👍 1
r
Instead of a query, you could also try this:
Copy code
import * as Prisma from '@prisma/client'
console.log(Prisma.dmmf.datamodel)
This will give you the entire datamodel and whether the fields are required or not
🎉 3
d
Amazing! Thanks so much, that’s just what I was hoping for.
💯 1