Skip to main content
Glama

Prisma MCP Server

Official
by prisma
Apache 2.0
4
44,192
  • Linux
  • Apple
DbPush.ts8.27 kB
import type { PrismaConfigInternal } from '@prisma/config' import { arg, canPrompt, checkUnsupportedDataProxy, Command, format, formatms, getCommandWithExecutor, HelpError, inferDirectoryConfig, isError, loadEnvFile, loadSchemaContext, MigrateTypes, } from '@prisma/internals' import { bold, dim, green, red, yellow } from 'kleur/colors' import prompt from 'prompts' import { Migrate } from '../Migrate' import type { EngineResults } from '../types' import { aiAgentConfirmationCheckpoint } from '../utils/ai-safety' import { ensureDatabaseExists, parseDatasourceInfo } from '../utils/ensureDatabaseExists' import { DbPushIgnoreWarningsWithFlagError } from '../utils/errors' import { printDatasource } from '../utils/printDatasource' export class DbPush implements Command { public static new(): DbPush { return new DbPush() } private static help = format(` ${process.platform === 'win32' ? '' : '🙌 '}Push the state from your Prisma schema to your database ${bold('Usage')} ${dim('$')} prisma db push [options] ${bold('Options')} -h, --help Display this help message --config Custom path to your Prisma config file --schema Custom path to your Prisma schema --accept-data-loss Ignore data loss warnings --force-reset Force a reset of the database before push --skip-generate Skip triggering generators (e.g. Prisma Client) ${bold('Examples')} Push the Prisma schema state to the database ${dim('$')} prisma db push Specify a schema ${dim('$')} prisma db push --schema=./schema.prisma Ignore data loss warnings ${dim('$')} prisma db push --accept-data-loss `) public async parse(argv: string[], config: PrismaConfigInternal): Promise<string | Error> { const args = arg( argv, { '--help': Boolean, '-h': '--help', '--accept-data-loss': Boolean, '--force-reset': Boolean, '--skip-generate': Boolean, '--schema': String, '--config': String, '--telemetry-information': String, }, false, ) if (isError(args)) { return this.help(args.message) } if (args['--help']) { return this.help() } await loadEnvFile({ schemaPath: args['--schema'], printMessage: true, config }) const schemaContext = await loadSchemaContext({ schemaPathFromArg: args['--schema'], schemaPathFromConfig: config.schema, schemaEngineConfig: config, }) const { migrationsDirPath } = inferDirectoryConfig(schemaContext, config) checkUnsupportedDataProxy({ cmd: 'db push', schemaContext }) const datasourceInfo = parseDatasourceInfo(schemaContext.primaryDatasource) const adapter = config.engine === 'js' ? await config.adapter() : undefined printDatasource({ datasourceInfo, adapter }) const schemaFilter: MigrateTypes.SchemaFilter = { externalTables: config.tables?.external ?? [], externalEnums: config.enums?.external ?? [], } const migrate = await Migrate.setup({ schemaEngineConfig: config, migrationsDirPath, schemaContext, schemaFilter, extensions: config['extensions'], }) // `ensureDatabaseExists` is not compatible with WebAssembly. if (!adapter) { try { // Automatically create the database if it doesn't exist const wasDbCreated = await ensureDatabaseExists(schemaContext.primaryDatasource) if (wasDbCreated) { process.stdout.write('\n' + wasDbCreated + '\n') } } catch (e) { process.stdout.write('\n') // empty line throw e } } let wasDatabaseReset = false if (args['--force-reset']) { process.stdout.write('\n') aiAgentConfirmationCheckpoint() try { await migrate.reset() } catch (e) { await migrate.stop() throw e } let successfulResetMsg = `The ${datasourceInfo.prettyProvider} database` if (datasourceInfo.dbName) { successfulResetMsg += ` "${datasourceInfo.dbName}"` } const schemasLength = datasourceInfo.schemas?.length || 0 // If schemas are defined in the datasource block, print them if (datasourceInfo.schemas && schemasLength > 0) { successfulResetMsg += ` schema${schemasLength > 1 ? 's' : ''} "${datasourceInfo.schemas.join(', ')}"` } // Otherwise, print the schema if it's defined in the connection string else if (datasourceInfo.schema) { successfulResetMsg += ` schema "${datasourceInfo.schema}"` } if (datasourceInfo.dbLocation) { successfulResetMsg += ` at "${datasourceInfo.dbLocation}"` } successfulResetMsg += ` ${schemasLength > 1 ? 'were' : 'was'} successfully reset.\n` process.stdout.write(successfulResetMsg) wasDatabaseReset = true } const before = Math.round(performance.now()) let migration: EngineResults.SchemaPush try { migration = await migrate.push({ force: args['--accept-data-loss'], }) } catch (e) { await migrate.stop() throw e } if (migration.unexecutable && migration.unexecutable.length > 0) { const messages: string[] = [] messages.push(`${bold(red('\n⚠️ We found changes that cannot be executed:\n'))}`) for (const item of migration.unexecutable) { messages.push(` • ${item}`) } process.stdout.write('\n') // empty line await migrate.stop() throw new Error(`${messages.join('\n')}\n You may use the --force-reset flag to drop the database before push like ${bold( green(getCommandWithExecutor('prisma db push --force-reset')), )} ${bold(red('All data will be lost.'))} `) } if (migration.warnings && migration.warnings.length > 0) { process.stdout.write(bold(yellow(`\n⚠️ There might be data loss when applying the changes:\n\n`))) for (const warning of migration.warnings) { process.stdout.write(` • ${warning}\n\n`) } process.stdout.write('\n') // empty line if (!args['--accept-data-loss']) { if (!canPrompt()) { await migrate.stop() throw new DbPushIgnoreWarningsWithFlagError() } process.stdout.write('\n') // empty line const confirmation = await prompt({ type: 'confirm', name: 'value', message: `Do you want to ignore the warning(s)?`, }) if (!confirmation.value) { process.stdout.write('Push cancelled.\n') await migrate.stop() // Return SIGINT exit code to signal that the process was cancelled. process.exit(130) } try { await migrate.push({ force: true, }) } catch (e) { await migrate.stop() throw e } } } await migrate.stop() if (!wasDatabaseReset && migration.warnings.length === 0 && migration.executedSteps === 0) { process.stdout.write(`\nThe database is already in sync with the Prisma schema.\n`) } else { const migrationTimeMessage = `Done in ${formatms(Math.round(performance.now()) - before)}` const rocketEmoji = process.platform === 'win32' ? '' : '🚀 ' const migrationSuccessStdMessage = 'Your database is now in sync with your Prisma schema.' const migrationSuccessMongoMessage = 'Your database indexes are now in sync with your Prisma schema.' // Favor the adapter if any, fallback to the provider defined in the schema const provider = adapter?.provider ?? schemaContext.primaryDatasource?.activeProvider process.stdout.write( `\n${rocketEmoji}${ provider === 'mongodb' ? migrationSuccessMongoMessage : migrationSuccessStdMessage } ${migrationTimeMessage}\n`, ) } // Run if not skipped if (!process.env.PRISMA_MIGRATE_SKIP_GENERATE && !args['--skip-generate']) { await migrate.tryToRunGenerate(datasourceInfo) } return `` } public help(error?: string): string | HelpError { if (error) { return new HelpError(`\n${bold(red(`!`))} ${error}\n${DbPush.help}`) } return DbPush.help } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/prisma/prisma'

If you have feedback or need assistance with the MCP directory API, please join our Discord server