Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update and read issues with @prisma/adapter-planetscale #21592

Closed
Murtatrxx opened this issue Oct 23, 2023 · 14 comments · Fixed by #21706
Closed

Update and read issues with @prisma/adapter-planetscale #21592

Murtatrxx opened this issue Oct 23, 2023 · 14 comments · Fixed by #21706
Assignees
Labels
Milestone

Comments

@Murtatrxx
Copy link

Murtatrxx commented Oct 23, 2023

Bug description

Prisma is behaving very strangely here.

So I'm trying to update my data in the database, I am doing everything right (AFAIK) but it just doesn't update or upsert any of my data. When I do try {} catch {}, I can't find anything because it doesn't throw any error, when updating or upserting, it just returns undefined or null.

Writes are fine, reads are mostly fine although I'm experiencing some kind of different issue there (I maybe can open another issue for that one) mostly unrelated.

Things I tried are these;

  1. Regenerating Prisma client
  2. Run "prisma db push" (It said the database was already in sync)
  3. Check if I can update data using the dashboard console or a UI tool like TablePlus (they both did)
  4. Asked Prisma community (they said open an issue)
  5. Disabled some of PlanetScale's features like Safe Schema Migrations (with no luck)
  6. Tried upgrading to 5.4.2
  7. Switching to a different database branch

How to reproduce

I'm connecting Prisma through the serverless driver that you guys added support for recently.
Here's my code that makes those problems;

import logger from '@logger';

import { connect } from '@planetscale/database';
import { PrismaPlanetScale } from '@prisma/adapter-planetscale';
import { PrismaClient } from '@prisma/client';
const undiciFetch = fetch;

// Initialize Prisma Client with the PlanetScale serverless database driver
const connection = connect({ url: process.env.DATABASE_URL, fetch: undiciFetch });
const adapter = new PrismaPlanetScale(connection);

export const prismaClient = new PrismaClient({
  log: ['error', 'info', 'warn'],
  adapter,
});

prismaClient.$connect().then(async () => {
  logger.info('Prisma initialized successfully');
  const data = await prismaClient.guild.update({
     where: { guildId: "Some valid guild Id" },
     data: { locale: "TR" },
     select: { locale: true }
}).then((data) => {
    logger.info(data); // undefined
  }).catch((err) => console.error(err));
  console.log(data); // also undefined
}).catch((err) => {
  logger.error('Prisma couldn\'t connect');
  console.log(err);
});

or

const data = await prismaClient.guild.upsert({
     where: { guildId: "Some valid guild Id" },
     update: { locale: "TR" },
     create: { guildId: "guildId", locale: "TR" }
     select: { locale: true }
}).then((data) => {
    logger.info(JSON.stringify(data));
  }).catch((err) => console.error(err));
  console.log(data);
  
  /* 
  prisma:error
Invalid `prismaClient.guild.upsert()` invocation in
c:\Users\user\OneDrive\Documents\bot\src\index.ts:271:45

Query upsertOneGuild is required to return data, but found no record(s).
This error originated either by throwing inside an async function without a catch block or rejecting a promise not handled with .catch(). The promise was rejected with the reason:
PrismaClientUnknownRequestError:
Invalid `prismaClient.guild.upsert()` invocation in
c:\Users\user\OneDrive\Documents\bot\src\index.ts:271:45

  270 public async testFn(guild: Guild, locale: Locale) {
   at Registry.updateGuildLocale (c:\Users\user\OneDrive\Documents\bot\src\index.ts:271:20) {
  clientVersion: '5.4.1'
}
*/

Expected behavior

Should update and upsert data without any issues.

Prisma information

model Guild {
  guildId           String            @id @unique @db.Char(18)
  locale            Locale?
  isPremiumActive   Boolean
  acessors          User[]
  enabledCategories Json?
  disabledCommands  Json?
  ModerationModule  ModerationModule?
  GiveawayModule    GiveawayModule?
}

model User {
  userId          String   @id @unique @db.Char(18)
  locale          Locale?
  username        String   @db.VarChar(32)
  isPremiumActive Boolean
  blacklisted     Boolean?
  member          Member?
  guilds          Guild[]  @relation()

  @@index([userId])
}

model Member {
  userId      String       @id @unique @db.Char(18)
  user        User         @relation(fields: [userId], references: [userId])
  incognito   Boolean
  infractions Infraction[]
  level       Int          @default(0) @db.UnsignedTinyInt
  notes       String?
}

// Moderation

model ModerationModule {
  id                          String @id @unique @default(UUID())
  guild                       Guild  @relation(fields: [guildId], references: [guildId])
  guildId                     String @unique @db.Char(18)
  rules                       Json?
  autoSlowmodeEnabledChannels Json?
  moderatorRoleId             Int?
  logsChannelId               Int // TODO: More types of logging for channels should be added
}

model Infraction {
  id String @id @default(cuid())

  type   InfractionType
  reason String         @db.Text

  memberId String @db.Char(18)
  Member   Member @relation(fields: [memberId], references: [userId])

  @@index([memberId])
}

enum InfractionType {
  TIMEOUT
  WARNING
}

// Giveaway

model GiveawayModule {
  id               String @id @unique @default(cuid())
  guild            Guild  @relation(fields: [guildId], references: [guildId])
  guildId          String @unique
  ongoingGiveaways Json?
}

model Giveaway {
  id             String    @id @unique @default(cuid())
  title          String    @db.VarChar(30)
  description    String?   @db.Text
  rewards        Json
  maxJoinerCount Int       @db.Int
  startDate      DateTime?
  endDate        DateTime
}

enum Category {
  UTILITIES
  MODERATION
  LEVELING
  GIVEAWAY
}

enum Locale {
  TR
  EN
  FR
}

generator client {
  provider        = "prisma-client-js"
  previewFeatures = ["driverAdapters"]
}

datasource db {
  url          = env("DATABASE_TEST_URL")
  provider     = "mysql"
  relationMode = "prisma"
}
// Add your code using Prisma Client

Environment & setup

  • OS: Windows
  • Database: PlanetScale
  • Node.js version: 18.16

Prisma Version

Same behavior on 5.4.1 and 5.4.2

prisma                  : 5.4.2
@prisma/client          : 5.4.2
Current platform        : windows
Query Engine (Node-API) : libquery-engine ac9d7041ed77bcc8a8dbd2ab6616b39013829574 (at node_modules\@prisma\engines\query_engine-windows.dll.node)
Schema Engine           : schema-engine-cli ac9d7041ed77bcc8a8dbd2ab6616b39013829574 (at node_modules\@prisma\engines\schema-engine-windows.exe)
Schema Wasm             : @prisma/prisma-schema-wasm 5.4.1-2.ac9d7041ed77bcc8a8dbd2ab6616b39013829574
Default Engines Hash    : ac9d7041ed77bcc8a8dbd2ab6616b39013829574
Studio                  : 0.494.0
Preview Features        : driverAdapters
@Murtatrxx Murtatrxx added the kind/bug A reported bug. label Oct 23, 2023
@Murtatrxx
Copy link
Author

Please correct me if I'm doing something stupid, I know this looks very hilarious.

@Murtatrxx
Copy link
Author

I'll try my best to create a standalone repro repo yeah

@miguelff miguelff added topic: driverAdapters team/client Issue for team Client. bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. labels Oct 24, 2023
@Murtatrxx
Copy link
Author

Murtatrxx commented Oct 25, 2023

Can confirm that this happens only when driver adapters are used to form connections

@Murtatrxx
Copy link
Author

// Import required dependencies
import { PrismaClient } from '@prisma/client';

const client = new PrismaClient();

console.log(await client.guild.update({
  where: { guildId: '801050779107590144' },
  data: { locale: 'FR' },
})); // Data updates and comes as expected

The code above works as expected.
While this one does not;

// Import required dependencies
import { connect } from '@planetscale/database';
import { PrismaPlanetScale } from '@prisma/adapter-planetscale';
import { PrismaClient } from '@prisma/client';
import { fetch as undiciFetch } from 'undici';

// Initialize Prisma Client with the PlanetScale serverless database driver
const connection = connect({ url: 'mysql://agdynvln2cbiimhkmfrl:pscale_pw*********************@aws.connect.psdb.cloud/test?sslaccept=strict', fetch: undiciFetch });
const adapter = new PrismaPlanetScale(connection);
const client = new PrismaClient({ adapter });

console.log(await client.guild.update({
  where: { guildId: '801050779107590144' },
  data: { locale: 'FR' },
})); // null

@Jolg42 Jolg42 changed the title I can't UPDATE my data I can't UPDATE my data when using @prisma/adapter-planetscale driver adapter Oct 25, 2023
@Murtatrxx Murtatrxx changed the title I can't UPDATE my data when using @prisma/adapter-planetscale driver adapter @prisma/adapter-planetscale driver adapter issues Oct 26, 2023
@Murtatrxx
Copy link
Author

the read issue I mentioned earlier can also be caused by this (?)

@janpio janpio changed the title @prisma/adapter-planetscale driver adapter issues update() does not work with @prisma/adapter-planetscale Oct 26, 2023
@janpio janpio added the topic: upsert nested upsert label Oct 26, 2023
@janpio janpio changed the title update() does not work with @prisma/adapter-planetscale update()/upsert() does not work with @prisma/adapter-planetscale Oct 26, 2023
@janpio
Copy link
Member

janpio commented Oct 26, 2023

I updated the issue title @Murtatrxx so it can help us understand what is going wrong for you. Does it match what you are reporting now?

@Murtatrxx
Copy link
Author

Yes, it does, at least for now if I find more issues related to this, I'll try to update it accordingly

@Murtatrxx
Copy link
Author

Murtatrxx commented Oct 27, 2023

After some more testing, the read issue I mentioned previously is also caused by this driverAdapter, let me also introduce that;
Read issue that I'm talking about is Prisma delivering incomplete data:

// Import required dependencies
import { connect } from '@planetscale/database';
import { PrismaPlanetScale } from '@prisma/adapter-planetscale';
import { PrismaClient } from '@prisma/client';
import { fetch as undiciFetch } from 'undici';

// Initialize Prisma Client with the PlanetScale serverless database driver
const connection = connect({ url: 'mysql://************@aws.connect.psdb.cloud/test?sslaccept=strict', fetch: undiciFetch });
const adapter = new PrismaPlanetScale(connection);
const client = new PrismaClient({ adapter });

console.log(await client.guild.findFirst());
{
  guildId: '8', // The actual data is 801050779107590144
  locale: 'FR',
  isPremiumActive: false,
}
// Whereas this produces expected results
import { PrismaClient } from '@prisma/client';
const client = new PrismaClient();

console.log(await client.guild.findFirst());
{
  guildId: '801050779107590144', // The actual data
  locale: 'FR',
  isPremiumActive: false,
}

double checked the results by doing a queries to my DB using the built-in console and TablePlus, confirmed DB actually stores correct values.

@Murtatrxx Murtatrxx changed the title update()/upsert() does not work with @prisma/adapter-planetscale Update and read issues with @prisma/adapter-planetscale Oct 27, 2023
@janpio
Copy link
Member

janpio commented Oct 27, 2023

I would prefer you to open a second issue for this different, second problem. Thank you.

@Murtatrxx
Copy link
Author

But it is related to this

@Murtatrxx
Copy link
Author

in the adapter, I listed the issues I encountered

@SevInf SevInf self-assigned this Oct 30, 2023
@SevInf SevInf added bug/2-confirmed Bug has been reproduced and confirmed. and removed bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. labels Oct 31, 2023
SevInf added a commit that referenced this issue Oct 31, 2023
`CHAR` db type does not mean single character. It should be mapped to
Text type instead.

Fix #21592
@SevInf
Copy link
Contributor

SevInf commented Oct 31, 2023

@Murtatrxx I can confirm that both problems you are experiencing have the same cause, so no need for second issue.
Fix is also on it's way, I'll let you know when you can test it.

@Jolg42 Jolg42 added this to the 5.6.0 milestone Oct 31, 2023
SevInf added a commit that referenced this issue Nov 1, 2023
`CHAR` db type does not mean single character. It should be mapped to
Text type instead.

Fix #21592
@SevInf
Copy link
Contributor

SevInf commented Nov 1, 2023

@Murtatrxx the issue is fixed and will be published as a part of 5.6.0. If you want to verify that fix works for you, you can try snapshot version 5.6.0-dev.52 (both client and adapter packages). We don't recommend that you use dev snapshot in production, but it is enough to verify the fix.

@Murtatrxx
Copy link
Author

Murtatrxx commented Nov 1, 2023

Yea thanks, I'll try that snapshot, and will soon be in touch with you

Update: Yes, it's indeed fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants