question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

DB creation fails: "'timestamp without time zone' literal cannot be generated for a UTC DateTime"

See original GitHub issue

After upgrading the Npgsql package from 5.0.3 to 6.0.0, it was no longer possible for us to create a new database using DbContext.Context.Migrate() because the following exception would occur:

System.InvalidCastException : 'timestamp without time zone' literal cannot be generated for a UTC DateTime
  Stack Trace: 
NpgsqlTimestampTypeMapping.GenerateLiteralCore(Object value)
NpgsqlTimestampTypeMapping.GenerateNonNullSqlLiteral(Object value)
MigrationsSqlGenerator.DefaultValue(Object defaultValue, String defaultValueSql, String columnType, MigrationCommandListBuilder builder)
NpgsqlMigrationsSqlGenerator.ColumnDefinition(String schema, String table, String name, ColumnOperation operation, IModel model, MigrationCommandListBuilder builder)
MigrationsSqlGenerator.ColumnDefinition(AddColumnOperation operation, IModel model, MigrationCommandListBuilder builder)
MigrationsSqlGenerator.Generate(AddColumnOperation operation, IModel model, MigrationCommandListBuilder builder, Boolean terminate)
NpgsqlMigrationsSqlGenerator.Generate(AddColumnOperation operation, IModel model, MigrationCommandListBuilder builder, Boolean terminate)
<.cctor>b__83_0(MigrationsSqlGenerator g, MigrationOperation o, IModel m, MigrationCommandListBuilder b)
MigrationsSqlGenerator.Generate(MigrationOperation operation, IModel model, MigrationCommandListBuilder builder)
MigrationsSqlGenerator.Generate(IReadOnlyList`1 operations, IModel model, MigrationsSqlGenerationOptions options)
NpgsqlMigrationsSqlGenerator.Generate(IReadOnlyList`1 operations, IModel model, MigrationsSqlGenerationOptions options)
Migrator.GenerateUpSql(Migration migration, MigrationsSqlGenerationOptions options)
<>c__DisplayClass16_2.<GetMigrationCommandLists>b__2()
Migrator.Migrate(String targetMigration)
RelationalDatabaseFacadeExtensions.Migrate(DatabaseFacade databaseFacade)
DbGlobals.UpgradeOrCreateDatabase(Action`1 postUpgradeAction, String connectionString) line 83

Here is a zip file with a small solution that reproduces the problem.

This is a ridiculously pared-down version of our database code; it turned out that none of the actual entity classes were needed to reproduce this. Instead, only the migrations were needed.

While debugging, I was very surprised to find out that the BuildTargetModel method of every single migration is called. This behavior (presumably driven by EF Core) seems completely superfluous, since the main DbContextModelSnapshot contains a complete model and would allow the final database schema to be created directly, without running any migrations.

I mention this because the exception occurs after AddLastUpdatedDates.BuildTargetModel is called, and the final migration UpgradeNpgsqlToV6.BuildTargetModel is not called. If I delete the second-to-last migration, then the last migration is called*… so, I think efcore.pg is choking on something in that second-to-last migration. The exception still occurs if all the other migrations are removed, so I’ve deleted all migrations except the first one, the last one and the second-to-last one.

(* and then there is an exception about “column “last_updated” … does not exist’” but I assume that’s because I stripped out all the other migrations along with all the actual C# entity objects)

I don’t know how to see the npg source code or local variables in my debugger, so I hope you guys can figure out what’s causing this.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
rojicommented, Dec 29, 2021

The problem here is that you have UTC DateTimes as default values for columns of type timestamp without time zone; the new 6.0 timestamp behavior strictly enforces the UTC/non-UTC distinction - only non-UTC DateTimes can be inserted into timestamp without time zone, and only UTC DateTimes can be inserted into timestamp with time zone.

I have some possible ideas on how to allow existing migration code to continue working even in 6.0; but the best way around this is currently to go over the existing code and to change the DateTime Kind to correspond to the column type. Specifically for the columns added in the AddLastUpdatedDates migration, this means changing their default values from DateTimeKind.Utc to DateTimeKind.Unspecified. If these columns actually hold UTC data, then after the migration code is fixed, I recommend changing them from timestamp without time zone to timestamp with time zone, as that’s the proper PostgreSQL type for UTC data (see the migration guide for this).

If you’d rather not address this right away, you also have the option of using the legacy timestamp behavior via the flag, as detailed in the release notes.

1reaction
rojicommented, Dec 23, 2021

@qwertie thanks for the detailed info - I’ll take a look at this in the coming days.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Cannot write DateTime with Kind=UTC to PostgreSQL type ...
I have common problem. Cannot write DateTime with Kind=UTC to PostgreSQL type 'timestamp without time zone'. And I want to enable Legacy ...
Read more >
Datetime error with .NET 6 and PostgreSQL - Duong's Blog
NET 6, I ran into an datetime issue with the latest npgsql efcore provider. ... type 'timestamp with time zone', only UTC is...
Read more >
What is a valid use case for using TIMESTAMP WITHOUT ...
It is considered valid for some to use timestamp WITHOUT time zone in situations where (1) everything is in the same timezone or...
Read more >
PostgreSQL type 'timestamp with time zone', only UTC is ...
PostgreSQL type 'timestamp with time zone', only UTC is supported. Note that it's not possible to mix DateTimes with different Kinds in an...
Read more >
Cannot write DateTime with Kind=Local to PostgreSQL ...
InvalidCastException : Cannot write DateTime with Kind=Local to PostgreSQL type 'timestamp with time zone', only UTC is supported. Note that it's not ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found