Skip to content

Instantly share code, notes, and snippets.

@nikolasburk
Last active December 18, 2019 12:36
Show Gist options
  • Save nikolasburk/98e46b01117afb094f3f48df9a8dc245 to your computer and use it in GitHub Desktop.
Save nikolasburk/98e46b01117afb094f3f48df9a8dc245 to your computer and use it in GitHub Desktop.

I'm using these prisma2 versions:

{
  "dependencies": {
    "@prisma/photon": "alpha"
  },
  "devDependencies": {
    "prisma2": "alpha",
    "ts-node-dev": "^1.0.0-pre.44",
    "typescript": "^3.7.3"
  },
  "scripts": {
    "dev": "ts-node ./script.ts"
  }
}
$ yarn prisma2 -v
                
yarn run v1.19.1
$ /Users/nikolasburk/Desktop/coinflips/node_modules/.bin/prisma2 -v
prisma2@2.0.0-alpha.456, binary version: f7ec56a4274c64735e820bcd4686d6bd06d7bd9a

Scalar list support will be removed for MySQL and SQLite, and for PostgreSQL the implementation is now using PostgreSQL native scalar lists(arrays) for this (so the upgrade process also involves a bit of data wrangling due to the way how this was implemented before). This can be tested already on alpha.

The way how scalar lists are supported in Prisma today is as follows, consider this Prisma schema:

datasource db {
  provider = "postgresql"
  url      = "postgresql://nikolasburk:nikolasburk@localhost:5432/coinflips"
}

generator photon {
  provider = "photonjs"
}

model User {
  id        Int       @id
  name      String    @default("")
  coinflips Boolean[]
}

This the SQL schema that gets generated when mapped to the DB:

-- Table Definition ----------------------------------------------

CREATE TABLE "User" (
    id integer DEFAULT nextval('"User_id_seq"'::regclass) PRIMARY KEY,
    name text NOT NULL DEFAULT ''::text
);

-- Indices -------------------------------------------------------

CREATE UNIQUE INDEX "User_pkey" ON "User"(id int4_ops);

-- Table Definition ----------------------------------------------

CREATE TABLE "User_coinflips" (
    "nodeId" integer REFERENCES "User"(id) ON DELETE CASCADE,
    position integer,
    value boolean NOT NULL,
    CONSTRAINT "User_coinflips_pkey" PRIMARY KEY ("nodeId", position)
);

-- Indices -------------------------------------------------------

CREATE UNIQUE INDEX "User_coinflips_pkey" ON "User_coinflips"("nodeId" int4_ops,position int4_ops);

This means the data for the coinflips: Boolean[] list from the Prisma schema is actually stored in another table called User_coinflips which includes a foreign key called nodeId that points to a User record.

I'm going through the upgrade process right now to figure out a workaround so that people can still use their data that was previously available through Prisma's scalar lists.

Here's the envisioned workaround for MySQL and SQLite (note that PostgreSQL users alternatively can migrate their data to a native PostgreSQL array, more info below):

  1. Copy the User_coinflips table, e.g. using:

    CREATE TABLE "User_coinflips_COPY" AS 
    TABLE "User_coinflips"; 
  2. Add a primary key so it's compliant with the current Prisma conventions:

    ALTER TABLE "User_coinflips_COPY" ADD COLUMN ID SERIAL PRIMARY KEY;
  3. Drop the original User_coinflips database (otherwise the introspection in the next step will fail):

    DROP DATABASE "User_coinflips";
  4. Re-map this to your Prisma schema through introspection:

    prisma2 introspect --url="postgresql://nikolasburk:nikolasburk@localhost:5432/coinflips"
    

    This is the resulting Prisma schema:

    generator photon {
      provider = "photonjs"
    }
    
    datasource db {
      provider = "postgresql"
      url      = "postgresql://nikolasburk:nikolasburk@localhost:5432/coinflips"
    }
    
    model User {
      id   Int    @id
      name String @default("")
    }
    
    model User_coinflips_COPY {
      id       Int      @id
      nodeId   Int?
      position Int?
      value    Boolean?
    }
  5. Manually add the coinflips relation:

    model User {
      id        Int                   @id
      name      String                @default("")
    +  coinflips User_coinflips_COPY[]
    }
  6. Re-generate Photon.js:

    prisma2 generate
    

In your application code, you can now adjust the Photon.js API calls. To access the coinflips data, you will now have to always include it in your API calls:

const user = await photon.users.findOne({ 
  where: { id: 1 },
  include: {
    coinflips: {
      orderBy: { position: "asc" }
    }
  }
})

The orderBy is important to retain the order of the list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment