[Sql Server] prisma migrate error when using multiple relations to the same table
See original GitHub issueBug description
When I run npx prisma migrate dev --name initial
with a schema like mine, the migration fails.
How to reproduce
- Create a prisma project with my schema.
- Create Azure SQL resources with this script
- replace the {SERVER} variables in the .env file (example)
- run
npx prisma migrate dev --name initial --create-only
- the command will fail with the error message
Database already exists FK__Address__userId
- after this error, the migrations table is totally broken and there’s nothing I can do to fix it, so I have to either drop all the objects or recreate the database
- There’s actually two errors here:
-
I want
User
to have multiple instances ofAddress
, butAddress
shouldn’t have any relations with theUser
object. Because Prisma requires me to add this ‘Opposite Relation’, I created 3 distinct relations with theUser
object. All of them refer to the same FK, as indicated in this comment. Because all the relations point to the same column (userId), it should create just a single FK. Today, it’s trying to create 3, as you can see in the final migration file. -
the error message is saying the the database already exists, but it should say
Constraint already exists FK__Address__userId
Expected behavior
A successful migration is created and applied.
Log information
➜ deposter git:(sqlserver) ✗ DEBUG=* npx prisma migrate dev --name init --create-only
prisma:loadEnv project root found at /Users/luisrudge/code/deposter/package.json +0ms
prisma:tryLoadEnv Environment variables loaded from /Users/luisrudge/code/deposter/.env +0ms
[dotenv][DEBUG] did not match key and value when parsing line 1: # Environment variables declared in this file are automatically made available to Prisma.
[dotenv][DEBUG] did not match key and value when parsing line 2: # See the documentation for more detail: https://pris.ly/d/prisma-schema#using-environment-variables
[dotenv][DEBUG] did not match key and value when parsing line 3:
[dotenv][DEBUG] did not match key and value when parsing line 4: # Prisma supports the native connection string format for PostgreSQL, MySQL and SQLite.
[dotenv][DEBUG] did not match key and value when parsing line 5: # See the documentation for all the connection string options: https://pris.ly/d/connection-strings
[dotenv][DEBUG] did not match key and value when parsing line 6:
Environment variables loaded from .env
prisma:engines using NAPI: false +0ms
prisma:engines binaries to download query-engine, migration-engine, introspection-engine, prisma-fmt +0ms
Prisma schema loaded from prisma/schema.prisma
Datasource "db"
prisma:migrateEngine:rpc starting migration engine with binary: /Users/luisrudge/code/deposter/node_modules/@prisma/engines/migration-engine-darwin +0ms
prisma:migrateEngine:rpc SENDING RPC CALL {"id":1,"jsonrpc":"2.0","method":"devDiagnostic","params":{"migrationsDirectoryPath":"/Users/luisrudge/code/deposter/prisma/migrations"}} +5ms
prisma:migrateEngine:stderr Apr 01 15:20:41.536 INFO migration_engine: Starting migration engine RPC server git_hash="60ba6551f29b17d7d6ce479e5733c70d9c00860e" +0ms
prisma:migrateEngine:stderr Apr 01 15:20:41.579 INFO new_connection: tiberius::client::connection: Performing a TLS handshake +42ms
prisma:migrateEngine:stderr Apr 01 15:20:41.637 INFO new_connection: tiberius::client::connection: TLS handshake successful +57ms
prisma:migrateEngine:stderr Apr 01 15:20:41.816 INFO new_connection: tiberius::tds::stream::token: Database change from 'database-test-prisma' to 'master' +179ms
prisma:migrateEngine:stderr Apr 01 15:20:41.816 INFO new_connection: tiberius::tds::stream::token: Changed database context to 'database-test-prisma'. +1ms
prisma:migrateEngine:stderr Apr 01 15:20:41.816 INFO new_connection: tiberius::tds::stream::token: SQL collation change from None to windows-1252/windows-1252 +0ms
prisma:migrateEngine:stderr Apr 01 15:20:41.816 INFO new_connection: tiberius::tds::stream::token: Microsoft SQL Server version 3490119692 +0ms
prisma:migrateEngine:stderr Apr 01 15:20:41.816 INFO new_connection: tiberius::tds::stream::token: Packet size change from '4096' to '4096' +0ms
prisma:migrateEngine:stderr Apr 01 15:20:41.817 INFO quaint::single: Starting a mssql connection. +0ms
prisma:migrateEngine:stderr Apr 01 15:20:41.860 ERROR DevDiagnostic:list_migrations:query_raw{sql="SELECT [id], [checksum], [finished_at], [migration_name], [logs], [rolled_back_at], [started_at], [applied_steps_count] FROM [dbo].[_prisma_migrations] ORDER BY [started_at] ASC"}: tiberius::tds::stream::token: Invalid object name 'dbo._prisma_migrations'. code=208 +43ms
prisma:migrateEngine:stderr Apr 01 15:20:41.898 INFO DevDiagnostic:calculate_drift:new_connection: tiberius::client::connection: Performing a TLS handshake +38ms
prisma:migrateEngine:stderr Apr 01 15:20:41.949 INFO DevDiagnostic:calculate_drift:new_connection: tiberius::client::connection: TLS handshake successful +51ms
prisma:migrateEngine:stderr Apr 01 15:20:42.129 INFO DevDiagnostic:calculate_drift:new_connection: tiberius::tds::stream::token: Database change from 'shadow_database-test-prisma' to 'master' +181ms
prisma:migrateEngine:stderr Apr 01 15:20:42.129 INFO DevDiagnostic:calculate_drift:new_connection: tiberius::tds::stream::token: Changed database context to 'shadow_database-test-prisma'. +0ms
prisma:migrateEngine:stderr Apr 01 15:20:42.129 INFO DevDiagnostic:calculate_drift:new_connection: tiberius::tds::stream::token: SQL collation change from None to windows-1252/windows-1252 +0ms
prisma:migrateEngine:stderr Apr 01 15:20:42.129 INFO DevDiagnostic:calculate_drift:new_connection: tiberius::tds::stream::token: Microsoft SQL Server version 3490119692 +1ms
prisma:migrateEngine:stderr Apr 01 15:20:42.130 INFO DevDiagnostic:calculate_drift:new_connection: tiberius::tds::stream::token: Packet size change from '4096' to '4096' +0ms
prisma:migrateEngine:stderr Apr 01 15:20:42.130 INFO DevDiagnostic:calculate_drift: quaint::single: Starting a mssql connection. +0ms
prisma:migrateEngine:stderr Apr 01 15:20:49.215 INFO DevDiagnostic:validate_migrations:new_connection: tiberius::client::connection: Performing a TLS handshake +7s
prisma:migrateEngine:stderr Apr 01 15:20:49.274 INFO DevDiagnostic:validate_migrations:new_connection: tiberius::client::connection: TLS handshake successful +59ms
prisma:migrateEngine:stderr Apr 01 15:20:49.328 INFO DevDiagnostic:validate_migrations:new_connection: tiberius::tds::stream::token: Database change from 'shadow_database-test-prisma' to 'master' +53ms
prisma:migrateEngine:stderr Apr 01 15:20:49.328 INFO DevDiagnostic:validate_migrations:new_connection: tiberius::tds::stream::token: Changed database context to 'shadow_database-test-prisma'. +1ms
prisma:migrateEngine:stderr Apr 01 15:20:49.328 INFO DevDiagnostic:validate_migrations:new_connection: tiberius::tds::stream::token: SQL collation change from None to windows-1252/windows-1252 +0ms
prisma:migrateEngine:stderr Apr 01 15:20:49.328 INFO DevDiagnostic:validate_migrations:new_connection: tiberius::tds::stream::token: Microsoft SQL Server version 3490119692 +0ms
prisma:migrateEngine:stderr Apr 01 15:20:49.328 INFO DevDiagnostic:validate_migrations:new_connection: tiberius::tds::stream::token: Packet size change from '4096' to '4096' +0ms
prisma:migrateEngine:stderr Apr 01 15:20:49.328 INFO DevDiagnostic:validate_migrations: quaint::single: Starting a mssql connection. +0ms
prisma:migrateEngine:stderr Apr 01 15:20:49.530 INFO DevDiagnostic:validate_migrations:raw_cmd{cmd="-- CreateTable\nCREATE TABLE [dbo].[User] (\n [id] INT NOT NULL IDENTITY(1,1),\n [createdAt] DATETIME2 NOT NULL CONSTRAINT [DF__User__createdAt] DEFAULT CURRENT_TIMESTAMP,\n [updatedAt] DATETIME2 NOT NULL,\n [name] NVARCHAR(1000) NOT NULL,\n [email] NVARCHAR(1000) NOT NULL,\n [password] NVARCHAR(1000) NOT NULL,\n [storeId] INT NOT NULL,\n CONSTRAINT [PK__User__id] PRIMARY KEY ([id]),\n CONSTRAINT [User_email_unique] UNIQUE ([email]),\n CONSTRAINT [User_storeId_unique] UNIQUE ([storeId])\n);\n\n-- CreateTable\nCREATE TABLE [dbo].[Address] (\n [id] INT NOT NULL IDENTITY(1,1),\n [createdAt] DATETIME2 NOT NULL CONSTRAINT [DF__Address__createdAt] DEFAULT CURRENT_TIMESTAMP,\n [updatedAt] DATETIME2 NOT NULL,\n [name] NVARCHAR(1000) NOT NULL,\n [contactName] NVARCHAR(1000) NOT NULL,\n [zipCode] NVARCHAR(1000) NOT NULL,\n [streetName] NVARCHAR(1000) NOT NULL,\n [streetNumber] NVARCHAR(1000) NOT NULL,\n [district] NVARCHAR(1000) NOT NULL,\n [complement] NVARCHAR(1000) NOT NULL,\n [userId] INT NOT NULL,\n CONSTRAINT [PK__Address__id] PRIMARY KEY ([id]),\n CONSTRAINT [Address_userId_unique] UNIQUE ([userId])\n);\n\n-- CreateTable\nCREATE TABLE [dbo].[Order] (\n [id] INT NOT NULL IDENTITY(1,1),\n [createdAt] DATETIME2 NOT NULL CONSTRAINT [DF__Order__createdAt] DEFAULT CURRENT_TIMESTAMP,\n [updatedAt] DATETIME2 NOT NULL,\n [customerId] INT NOT NULL,\n [addressId] INT NOT NULL,\n [storeId] INT NOT NULL,\n CONSTRAINT [PK__Order__id] PRIMARY KEY ([id]),\n CONSTRAINT [Order_addressId_unique] UNIQUE ([addressId])\n);\n\n-- CreateTable\nCREATE TABLE [dbo].[Store] (\n [id] INT NOT NULL IDENTITY(1,1),\n [createdAt] DATETIME2 NOT NULL CONSTRAINT [DF__Store__createdAt] DEFAULT CURRENT_TIMESTAMP,\n [updatedAt] DATETIME2 NOT NULL,\n [name] NVARCHAR(1000) NOT NULL,\n CONSTRAINT [PK__Store__id] PRIMARY KEY ([id])\n);\n\n-- AddForeignKey\nALTER TABLE [dbo].[User] ADD CONSTRAINT [FK__User__storeId] FOREIGN KEY ([storeId]) REFERENCES [dbo].[Store]([id]) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE [dbo].[Address] ADD CONSTRAINT [FK__Address__userId] FOREIGN KEY ([userId]) REFERENCES [dbo].[User]([id]) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE [dbo].[Address] ADD CONSTRAINT [FK__Address__userId] FOREIGN KEY ([userId]) REFERENCES [dbo].[User]([id]) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE [dbo].[Address] ADD CONSTRAINT [FK__Address__userId] FOREIGN KEY ([userId]) REFERENCES [dbo].[User]([id]) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE [dbo].[Order] ADD CONSTRAINT [FK__Order__customerId] FOREIGN KEY ([customerId]) REFERENCES [dbo].[User]([id]) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE [dbo].[Order] ADD CONSTRAINT [FK__Order__addressId] FOREIGN KEY ([addressId]) REFERENCES [dbo].[Address]([id]) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE [dbo].[Order] ADD CONSTRAINT [FK__Order__storeId] FOREIGN KEY ([storeId]) REFERENCES [dbo].[Store]([id]) ON DELETE CASCADE ON UPDATE CASCADE;\n"}: tiberius::tds::stream::token: Warning! The maximum key length for a nonclustered index is 1700 bytes. The index 'User_email_unique' has maximum length of 2000 bytes. For some combination of large values, the insert/update operation will fail. +202ms
prisma:migrateEngine:stderr Apr 01 15:20:49.530 ERROR DevDiagnostic:validate_migrations:raw_cmd{cmd="-- CreateTable\nCREATE TABLE [dbo].[User] (\n [id] INT NOT NULL IDENTITY(1,1),\n [createdAt] DATETIME2 NOT NULL CONSTRAINT [DF__User__createdAt] DEFAULT CURRENT_TIMESTAMP,\n [updatedAt] DATETIME2 NOT NULL,\n [name] NVARCHAR(1000) NOT NULL,\n [email] NVARCHAR(1000) NOT NULL,\n [password] NVARCHAR(1000) NOT NULL,\n [storeId] INT NOT NULL,\n CONSTRAINT [PK__User__id] PRIMARY KEY ([id]),\n CONSTRAINT [User_email_unique] UNIQUE ([email]),\n CONSTRAINT [User_storeId_unique] UNIQUE ([storeId])\n);\n\n-- CreateTable\nCREATE TABLE [dbo].[Address] (\n [id] INT NOT NULL IDENTITY(1,1),\n [createdAt] DATETIME2 NOT NULL CONSTRAINT [DF__Address__createdAt] DEFAULT CURRENT_TIMESTAMP,\n [updatedAt] DATETIME2 NOT NULL,\n [name] NVARCHAR(1000) NOT NULL,\n [contactName] NVARCHAR(1000) NOT NULL,\n [zipCode] NVARCHAR(1000) NOT NULL,\n [streetName] NVARCHAR(1000) NOT NULL,\n [streetNumber] NVARCHAR(1000) NOT NULL,\n [district] NVARCHAR(1000) NOT NULL,\n [complement] NVARCHAR(1000) NOT NULL,\n [userId] INT NOT NULL,\n CONSTRAINT [PK__Address__id] PRIMARY KEY ([id]),\n CONSTRAINT [Address_userId_unique] UNIQUE ([userId])\n);\n\n-- CreateTable\nCREATE TABLE [dbo].[Order] (\n [id] INT NOT NULL IDENTITY(1,1),\n [createdAt] DATETIME2 NOT NULL CONSTRAINT [DF__Order__createdAt] DEFAULT CURRENT_TIMESTAMP,\n [updatedAt] DATETIME2 NOT NULL,\n [customerId] INT NOT NULL,\n [addressId] INT NOT NULL,\n [storeId] INT NOT NULL,\n CONSTRAINT [PK__Order__id] PRIMARY KEY ([id]),\n CONSTRAINT [Order_addressId_unique] UNIQUE ([addressId])\n);\n\n-- CreateTable\nCREATE TABLE [dbo].[Store] (\n [id] INT NOT NULL IDENTITY(1,1),\n [createdAt] DATETIME2 NOT NULL CONSTRAINT [DF__Store__createdAt] DEFAULT CURRENT_TIMESTAMP,\n [updatedAt] DATETIME2 NOT NULL,\n [name] NVARCHAR(1000) NOT NULL,\n CONSTRAINT [PK__Store__id] PRIMARY KEY ([id])\n);\n\n-- AddForeignKey\nALTER TABLE [dbo].[User] ADD CONSTRAINT [FK__User__storeId] FOREIGN KEY ([storeId]) REFERENCES [dbo].[Store]([id]) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE [dbo].[Address] ADD CONSTRAINT [FK__Address__userId] FOREIGN KEY ([userId]) REFERENCES [dbo].[User]([id]) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE [dbo].[Address] ADD CONSTRAINT [FK__Address__userId] FOREIGN KEY ([userId]) REFERENCES [dbo].[User]([id]) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE [dbo].[Address] ADD CONSTRAINT [FK__Address__userId] FOREIGN KEY ([userId]) REFERENCES [dbo].[User]([id]) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE [dbo].[Order] ADD CONSTRAINT [FK__Order__customerId] FOREIGN KEY ([customerId]) REFERENCES [dbo].[User]([id]) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE [dbo].[Order] ADD CONSTRAINT [FK__Order__addressId] FOREIGN KEY ([addressId]) REFERENCES [dbo].[Address]([id]) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE [dbo].[Order] ADD CONSTRAINT [FK__Order__storeId] FOREIGN KEY ([storeId]) REFERENCES [dbo].[Store]([id]) ON DELETE CASCADE ON UPDATE CASCADE;\n"}: tiberius::tds::stream::token: There is already an object named 'FK__Address__userId' in the database. code=2714 +2ms
prisma:migrateEngine:rpc {
prisma:migrateEngine:rpc jsonrpc: '2.0',
prisma:migrateEngine:rpc error: {
prisma:migrateEngine:rpc code: 4466,
prisma:migrateEngine:rpc message: 'An error happened. Check the data field for details.',
prisma:migrateEngine:rpc data: {
prisma:migrateEngine:rpc is_panic: false,
prisma:migrateEngine:rpc message: 'Migration `20210401180847_init` failed to apply cleanly to a temporary database. \n' +
prisma:migrateEngine:rpc 'Error:\n' +
prisma:migrateEngine:rpc 'Database error\n' +
prisma:migrateEngine:rpc 'Database already exists FK__Address__userId\n' +
prisma:migrateEngine:rpc ' 0: sql_migration_connector::sql_database_migration_inferrer::validate_migrations\n' +
prisma:migrateEngine:rpc ' at migration-engine/connectors/sql-migration-connector/src/sql_database_migration_inferrer.rs:88\n' +
prisma:migrateEngine:rpc ' 1: migration_core::api::DevDiagnostic\n' +
prisma:migrateEngine:rpc ' at migration-engine/core/src/api.rs:95',
prisma:migrateEngine:rpc meta: [Object],
prisma:migrateEngine:rpc error_code: 'P3006'
prisma:migrateEngine:rpc }
prisma:migrateEngine:rpc },
prisma:migrateEngine:rpc id: 1
prisma:migrateEngine:rpc } +8s
Error: Error: P3006
Migration `20210401180847_init` failed to apply cleanly to a temporary database.
Error:
Database error
Database already exists FK__Address__userId
0: sql_migration_connector::sql_database_migration_inferrer::validate_migrations
at migration-engine/connectors/sql-migration-connector/src/sql_database_migration_inferrer.rs:88
1: migration_core::api::DevDiagnostic
at migration-engine/core/src/api.rs:95
at Object.<anonymous> (/Users/luisrudge/code/deposter/node_modules/prisma/build/index.js:55676:26)
at MigrateEngine.handleResponse (/Users/luisrudge/code/deposter/node_modules/prisma/build/index.js:55551:38)
at LineStream.<anonymous> (/Users/luisrudge/code/deposter/node_modules/prisma/build/index.js:55636:18)
at LineStream.emit (node:events:378:20)
at LineStream.EventEmitter.emit (node:domain:470:12)
at addChunk (node:internal/streams/readable:313:12)
at readableAddChunk (node:internal/streams/readable:288:9)
at LineStream.Readable.push (node:internal/streams/readable:227:10)
at LineStream._pushBuffer (/Users/luisrudge/code/deposter/node_modules/prisma/build/index.js:55391:19)
at LineStream._transform (/Users/luisrudge/code/deposter/node_modules/prisma/build/index.js:55385:10)
Prisma information
https://gist.github.com/luisrudge/7b246dfb061a69b56fc8237786b6b980#file-migration-sql-L56-L63
Environment & setup
Environment variables loaded from .env
prisma : 2.20.1
@prisma/client : 2.20.1
Current platform : darwin
Query Engine : query-engine 60ba6551f29b17d7d6ce479e5733c70d9c00860e (at node_modules/@prisma/engines/query-engine-darwin)
Migration Engine : migration-engine-cli 60ba6551f29b17d7d6ce479e5733c70d9c00860e (at node_modules/@prisma/engines/migration-engine-darwin)
Introspection Engine : introspection-core 60ba6551f29b17d7d6ce479e5733c70d9c00860e (at node_modules/@prisma/engines/introspection-engine-darwin)
Format Binary : prisma-fmt 60ba6551f29b17d7d6ce479e5733c70d9c00860e (at node_modules/@prisma/engines/prisma-fmt-darwin)
Default Engines Hash : 60ba6551f29b17d7d6ce479e5733c70d9c00860e
Studio : 0.365.0
Preview Features : microsoftSqlServer
Issue Analytics
- State:
- Created 2 years ago
- Comments:10 (8 by maintainers)
Top GitHub Comments
Oh, of course. that makes a lot of sense. it’s been a while since I last modeled a database. YOu inverted the FKs to make sure they’re present in the user/order objects instead of the Address object, right?
I’ll give this a go. If I find something weird, I’ll ping you. Thank you so much for your patience and help!
Error message should be less misleading in next release: https://github.com/prisma/prisma/issues/6547#issuecomment-822697209