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.

SQL type for string has changed after v3.*

See original GitHub issue

Hi team,

A lot of appreciation to your work. Thanks a lot for this great package.

The issue

Some time ago I have started work in one opensource project. First PR is bump the project and dependencies from .NET Core 3.1 to .NET 6.

The project is a package manager and it supports different DBs, using EF Core as ORM & code-first approach.

So at stable versions there is a Pomelo.EntityFrameworkCore.MySql v3.1.0 Now I’m trying to use Pomelo.EntityFrameworkCore.MySql v6.0.0

And it seems like some type mapping logic has changed. The problem is in a strings with a large length (e.g. 4000 symbols)

When I have launched EF migrations on a 3.1 they use longtext MySQL type for this fields.

CREATE TABLE `Packages` (
  `Key` int NOT NULL AUTO_INCREMENT,
  `Id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `Authors` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL,
  `Description` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL,
  `Downloads` bigint NOT NULL,
  `HasReadme` tinyint(1) NOT NULL,
  `Language` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `Listed` tinyint(1) NOT NULL,
  `MinClientVersion` varchar(44) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `Published` datetime(6) NOT NULL,
  `RequireLicenseAcceptance` tinyint(1) NOT NULL,
  `Summary` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL,
  `Title` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `IconUrl` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL,
  `LicenseUrl` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL,
  `ProjectUrl` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL,
  `RepositoryUrl` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL,
  `RepositoryType` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `Tags` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL,
  `RowVersion` timestamp(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
  `Version` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `IsPrerelease` tinyint(1) NOT NULL DEFAULT 0,
  `SemVerLevel` int NOT NULL DEFAULT 0,
  `OriginalVersion` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `ReleaseNotes` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL,
  `HasEmbeddedIcon` tinyint(1) NOT NULL DEFAULT 0,
   ...
);

Now on 6.0 it uses varchar(...) as a type:

CREATE TABLE `Packages` (
    `Key` int NOT NULL AUTO_INCREMENT,
    `Id` varchar(128) NOT NULL,
    `Authors` varchar(4000) NULL,
    `Description` varchar(4000) NULL,
    `Downloads` bigint NOT NULL,
    `HasReadme` tinyint(1) NOT NULL,
    `Language` varchar(20) NULL,
    `Listed` tinyint(1) NOT NULL,
    `MinClientVersion` varchar(44) NULL,
    `Published` datetime(6) NOT NULL,
    `RequireLicenseAcceptance` tinyint(1) NOT NULL,
    `Summary` varchar(4000) NULL,
    `Title` varchar(256) NULL,
    `IconUrl` varchar(4000) NULL,
    `LicenseUrl` varchar(4000) NULL,
    `ProjectUrl` varchar(4000) NULL,
    `RepositoryUrl` varchar(4000) NULL,
    `RepositoryType` varchar(100) NULL,
    `Tags` varchar(4000) NULL,
    `RowVersion` datetime(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
    `Version` varchar(64) NOT NULL,
    ...
);

Which causes the next error

Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs

So the questions are:

  • In which release this behavior was changed?
  • How I could manage the target type to avoid this situation? (I’ve tried HasColumnType(longtext), but had no success)

Configuration info

Further technical details

MySQL version: MySQL Ver 8.0.27 for Linux on x86_64 (MySQL Community Server - GPL) Operating system: Win10 Build 19044.1466 & Docker version 20.10.12, build e91ed57 Pomelo.EntityFrameworkCore.MySql version: 6.0.0


Thanks in advance!

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:1
  • Comments:6

github_iconTop GitHub Comments

3reactions
mishamytecommented, Jan 22, 2022

@lauxjpn thanks a lot for your explanation. It became completely clear for me

2reactions
lauxjpncommented, Jan 22, 2022

You could either remove the .HasMaxLength(4000) call or add a .HasColumnType("longtext") call (that then effectively ignores the length; see the Name4000Longtext property in my sample code).

In case you cannot do this, because other supported providers cannot deal with this, you might want to do those changes only for Pomelo.

A simple way to do this is to check the provider and then change the model as needed at the end of the OnModelCreating method:

if (Database.ProviderName == "Pomelo.EntityFrameworkCore.MySql")
{
    foreach (var property in modelBuilder.Model.GetEntityTypes()
                 .SelectMany(e => e.GetProperties())
                 .Where(p => p.ClrType == typeof(string) &&
                             p.GetMaxLength() >= 4000)) // chose whatever threshold you want
    {
        property.SetMaxLength(null);
    }
}

Applying this to my sample code results in the following CREATE TABLE statement:

CREATE TABLE `IceCreams` (
    `IceCreamId` int NOT NULL AUTO_INCREMENT,
    `NameDefault` longtext CHARACTER SET utf8mb4 NOT NULL,
    `NameLongtext` longtext CHARACTER SET utf8mb4 NOT NULL,
    `Name4000` longtext CHARACTER SET utf8mb4 NOT NULL,
    `Name4000Longtext` longtext CHARACTER SET utf8mb4 NOT NULL,
    CONSTRAINT `PK_IceCreams` PRIMARY KEY (`IceCreamId`)
) CHARACTER SET=utf8mb4;
Read more comments on GitHub >

github_iconTop Results From Across the Web

SQL Server changed my strings before running the query
If you have special characters that need to be preserved, use Unicode strings of type NVARCHAR instead of VARCHAR - it's that simple...
Read more >
SQL queries to change the column type
This article will show the way to change the data type of the columns in SQL Server 2019, MySQL Server, and PostgreSQL.
Read more >
Data type conversion (Database Engine) - SQL Server
When data from one object is moved to, compared with, or combined with data from another object, the data may have to be...
Read more >
Migration Guide: SQL, Datasets and DataFrame
In Spark 3.0 or earlier, NULL elements are converted to empty strings. To restore the behavior before Spark 3.1, you can set spark....
Read more >
Data types in Amazon Athena
When you run CREATE TABLE, you specify column names and the data type that each column can contain. Athena supports the data types...
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