Open seed-of-apricot opened 1 year ago
I can confirm this:
PS C:\Users\Jan\Documents\throwaway\19963> npx prisma migrate dev
Environment variables loaded from .env
Prisma schema loaded from prisma\schema.prisma
Datasource "db": SQL Server database
√ Enter a name for the new migration: ... change
Applying migration `20240522193038_change`
Error: P3018
A migration failed to apply. New migrations cannot be applied before the error is recovered from. Read more about how to resolve migration issues in a production database: https://pris.ly/d/migrate-resolve
Migration name: 20240522193038_change
Database error code: 134
Database error:
The variable name '@SQL' has already been declared. Variable names must be unique within a query batch or stored procedure.
The original schema I used:
And then I changed it to:
model Terrain {
id String @id @default(uuid())
createdAt DateTime @default(now())
deletedAt DateTime?
terrainType TerrainType @relation(fields: [terrainTypeId], references: [id])
terrainTypeId Int // change this to Int
// Plot Plot @relation(fields: [plotId], references: [id])
// plotId String
// @@index([plotId])
@@index([terrainTypeId])
}
model TerrainType {
id Int @id @default(autoincrement()) // change String to Int and uuid() to autoincrement()
name String
Terrain Terrain[]
}
model Feature {
id String @id @default(uuid())
createdAt DateTime @default(now())
deletedAt DateTime?
featureType FeatureType @relation(fields: [featureTypeId], references: [id])
featureTypeId Int // change this to Int
// Plot Plot @relation(fields: [plotId], references: [id])
// plotId String
// @@index([plotId])
@@index([featureTypeId])
}
model FeatureType {
id Int @id @default(autoincrement()) // change String to Int and uuid() to autoincrement()
name String
Feature Feature[]
}
The generated migration SQL:
/*
Warnings:
- You are about to alter the column `featureTypeId` on the `Feature` table. The data in that column could be lost. The data in that column will be cast from `NVarChar(1000)` to `Int`.
- You are about to alter the column `terrainTypeId` on the `Terrain` table. The data in that column could be lost. The data in that column will be cast from `NVarChar(1000)` to `Int`.
- The primary key for the `TerrainType` table will be changed. If it partially fails, the table could be left without primary key constraint.
- You are about to alter the column `id` on the `TerrainType` table. The data in that column could be lost. The data in that column will be cast from `String` to `Int`.
- The primary key for the `FeatureType` table will be changed. If it partially fails, the table could be left without primary key constraint.
- You are about to alter the column `id` on the `FeatureType` table. The data in that column could be lost. The data in that column will be cast from `String` to `Int`.
*/
BEGIN TRY
BEGIN TRAN;
-- DropForeignKey
ALTER TABLE [dbo].[Feature] DROP CONSTRAINT [Feature_featureTypeId_fkey];
-- DropForeignKey
ALTER TABLE [dbo].[Terrain] DROP CONSTRAINT [Terrain_terrainTypeId_fkey];
-- DropIndex
DROP INDEX [Feature_featureTypeId_idx] ON [dbo].[Feature];
-- DropIndex
DROP INDEX [Terrain_terrainTypeId_idx] ON [dbo].[Terrain];
-- AlterTable
ALTER TABLE [dbo].[Feature] ALTER COLUMN [featureTypeId] INT NOT NULL;
-- AlterTable
ALTER TABLE [dbo].[Terrain] ALTER COLUMN [terrainTypeId] INT NOT NULL;
-- RedefineTables
BEGIN TRANSACTION;
DECLARE @SQL NVARCHAR(MAX) = N''
SELECT @SQL += N'ALTER TABLE '
+ QUOTENAME(OBJECT_SCHEMA_NAME(PARENT_OBJECT_ID))
+ '.'
+ QUOTENAME(OBJECT_NAME(PARENT_OBJECT_ID))
+ ' DROP CONSTRAINT '
+ OBJECT_NAME(OBJECT_ID) + ';'
FROM SYS.OBJECTS
WHERE TYPE_DESC LIKE '%CONSTRAINT'
AND OBJECT_NAME(PARENT_OBJECT_ID) = 'TerrainType'
AND SCHEMA_NAME(SCHEMA_ID) = 'dbo'
EXEC sp_executesql @SQL
;
CREATE TABLE [dbo].[_prisma_new_TerrainType] (
[id] INT NOT NULL IDENTITY(1,1),
[name] NVARCHAR(1000) NOT NULL,
CONSTRAINT [TerrainType_pkey] PRIMARY KEY CLUSTERED ([id])
);
SET IDENTITY_INSERT [dbo].[_prisma_new_TerrainType] ON;
IF EXISTS(SELECT * FROM [dbo].[TerrainType])
EXEC('INSERT INTO [dbo].[_prisma_new_TerrainType] ([id],[name]) SELECT [id],[name] FROM [dbo].[TerrainType] WITH (holdlock tablockx)');
SET IDENTITY_INSERT [dbo].[_prisma_new_TerrainType] OFF;
DROP TABLE [dbo].[TerrainType];
EXEC SP_RENAME N'dbo._prisma_new_TerrainType', N'TerrainType';
DECLARE @SQL NVARCHAR(MAX) = N''
SELECT @SQL += N'ALTER TABLE '
+ QUOTENAME(OBJECT_SCHEMA_NAME(PARENT_OBJECT_ID))
+ '.'
+ QUOTENAME(OBJECT_NAME(PARENT_OBJECT_ID))
+ ' DROP CONSTRAINT '
+ OBJECT_NAME(OBJECT_ID) + ';'
FROM SYS.OBJECTS
WHERE TYPE_DESC LIKE '%CONSTRAINT'
AND OBJECT_NAME(PARENT_OBJECT_ID) = 'FeatureType'
AND SCHEMA_NAME(SCHEMA_ID) = 'dbo'
EXEC sp_executesql @SQL
;
CREATE TABLE [dbo].[_prisma_new_FeatureType] (
[id] INT NOT NULL IDENTITY(1,1),
[name] NVARCHAR(1000) NOT NULL,
CONSTRAINT [FeatureType_pkey] PRIMARY KEY CLUSTERED ([id])
);
SET IDENTITY_INSERT [dbo].[_prisma_new_FeatureType] ON;
IF EXISTS(SELECT * FROM [dbo].[FeatureType])
EXEC('INSERT INTO [dbo].[_prisma_new_FeatureType] ([id],[name]) SELECT [id],[name] FROM [dbo].[FeatureType] WITH (holdlock tablockx)');
SET IDENTITY_INSERT [dbo].[_prisma_new_FeatureType] OFF;
DROP TABLE [dbo].[FeatureType];
EXEC SP_RENAME N'dbo._prisma_new_FeatureType', N'FeatureType';
COMMIT;
-- CreateIndex
CREATE NONCLUSTERED INDEX [Terrain_terrainTypeId_idx] ON [dbo].[Terrain]([terrainTypeId]);
-- CreateIndex
CREATE NONCLUSTERED INDEX [Feature_featureTypeId_idx] ON [dbo].[Feature]([featureTypeId]);
-- AddForeignKey
ALTER TABLE [dbo].[Terrain] ADD CONSTRAINT [Terrain_terrainTypeId_fkey] FOREIGN KEY ([terrainTypeId]) REFERENCES [dbo].[TerrainType]([id]) ON DELETE NO ACTION ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE [dbo].[Feature] ADD CONSTRAINT [Feature_featureTypeId_fkey] FOREIGN KEY ([featureTypeId]) REFERENCES [dbo].[FeatureType]([id]) ON DELETE NO ACTION ON UPDATE CASCADE;
COMMIT TRAN;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
BEGIN
ROLLBACK TRAN;
END;
THROW
END CATCH
Definitely two DECLARE @SQL NVARCHAR(MAX) = N''
in there.
So changing the type of two primary keys that are part of a relation seems to trigger this.
Bug description
npx prisma migration
produces duplicate@SQL
declaration that results inHow to reproduce
Change the Prisma schema as shown below.
Expected behavior
The migration will be applied without errors.
I could apply it by manually removing the second
@SQL
declaration.Prisma information
Environment & setup
Prisma Version
(I always use
npx prisma
)