Re: OperationalError: (1253, "COLLATION 'utf8mb3_bin' is not valid for CHARACTER SET 'utf8mb4'")

Nagy Gabor <[email protected]>
Newsgroups gmane.comp.bug-tracking.roundup.user
Message-ID <20230616213123.150b935f@Dell>
Hi John,

Thanks for detailed response. Today I had time for some testing.
It is important to note that I am not very familiar in MySQL, I just
report some observations. (One of the good things in Roundup that I do
not have to deal with direct SQL commands. I was very happy - and
surprised - when I found Roundup, a very flexible bug tracker: That is
exactly what I looked for, I did not believe such an open source
project exists. It took a while until I understood how Roundup works,
but now I find it very handy.)

First of all, I have no clue how I managed to create utf8mb4 encoded
tables in my Roundup's sql database. Now I cannot create utf8mb4 table
with Roundup 2.1.0 or 2.2.0 (no sql patches applied) even if I set
mysql_charset = utf8mb4 in config.ini. This is mystery how my Roundup
created such tables
(I did not upgrade or configure mariadb after my utf8mb4 tables were
created.)

Now I think mysql_charset = utf8mb4 has no real effect in Roundup
2.1.0. The only effect I see in the mysqldump of the database is:

/*!40101 SET NAMES utf8mb4 */,

but the databases still looks like this:

CREATE TABLE `_status` (
...
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci;


Based on your previous email, the following patch (of back_mysql.py of
v2.1.0) solves the problems, plus the mysql_charset = utf8mb4 setting
in config.ini:

diff --git a/back_mysql.py.bak b/back_mysql.py
index b0ec1c6..7b128a4 100644
--- a/back_mysql.py.bak
+++ b/back_mysql.py
@@ -92,9 +92,9 @@ def db_create(config):
     kwargs = connection_dict(config)
     conn = MySQLdb.connect(**kwargs)
     cursor = conn.cursor()
-    command = "CREATE DATABASE %s"%config.RDBMS_NAME
+    command = "CREATE DATABASE %s COLLATE utf8mb4_unicode_ci"%config.RDBMS_NAME
     if sys.version_info[0] > 2:
-        command += ' CHARACTER SET utf8'
+        command += ' CHARACTER SET utf8mb4'
     logging.info(command)
     cursor.execute(command)
     conn.commit()
@@ -625,7 +625,7 @@ class Database(rdbms_common.Database):
                 raise
 
 class MysqlClass:
-    case_sensitive_equal = 'COLLATE utf8_bin ='
+    case_sensitive_equal = 'COLLATE utf8mb4_bin ='
 
     # TODO: AFAIK its version dependent for MySQL
     supports_subselects = False

Discussion:
1) The change to case_sensitive_equal = 'COLLATE utf8mb4_bin ='
eliminates the Error in the subject of this email on utf8mb4 tables.
(Unfortunately, utf8mb4_bin does not seem to be backward compatible,
because if I do exact_match_spec search with this patch applied in an
utf8mb3 table, I get the same error with the numbers 3 and 4
interchanged. Great...)

2) The patches on db_create() has the effect that 'roundup-admin
initalise' finally creates utf8mb4 encoded tables. I also tested the
implicit table creation (when you add a new class to schema.py), those
tables are also created with utf8mb4.
(The "COLLATE utf8_general_ci" change of Roundup v2.2.0 is not enough to
achieve this on my system.)

3) MySQL 8.0 documentation says this in
https://dev.mysql.com/doc/refman/8.0/en/charset-unicode-sets.html :
"utf8: An alias for utf8mb3. In MySQL 8.0, this alias is deprecated;
use utf8mb4 instead. utf8 is expected in a future release to become an
alias for utf8mb4."
So if we wait long enough, this problem might disappear automatically.
:)

+1) Of course, these hardcoded "utf8mb4 commands" in the source code are
ugly (those are proof of concept codes), this should be somehow
configurable, or the code should figure out (from mysql_charset) these
codeparts.

Regards,
Gábor

P.S. I also thank you for your quick response to my bug report for
the sorted() method of the class MultilinkHTMLProperty.

> Hi Gabor:
> 
> I'm sorry this is becoming such a chore.
> 
> In message <20230530144304.3e55d8e3@Dell>, Nagy Gabor writes:
> >1) Thanks for the detailed information. First of all, MySQL's partial
> >(3-bit) utf8 implementation is a shame. I am not happy...  
> 
> I agree.
> 
> >I have to convert my Roundup databases to utf8mb4 to support all utf8
> >characters, and it is not so evident as it sounds (thanks for the
> >links, btw):
> >https://dev.mysql.com/doc/refman/8.0/en/charset-unicode-conversion.html
> >I have to check that the "maximum permitted length" limitation does
> >not break anything, so I have to understand Roundup's SQL database,
> >which I did not wanted. :)  
> 
> I took a quick scan of the code in rdbms_common.py and back_mysql.py
> in the backends directory.
> 
> From that it looks like VARCHAR(255) is used for single character
> (I.E. ANSI/ASCII character set) represented values. For example
> encoded passwords, intervals. One Time Keys used to be VARCHAR but
> were converted to TEXT. So the conversion shouldn't matter as the
> fields will be the same size before/after.
> 
> The String type in Roundup is represented as TEXT in mysql. While
> strings can be large, files and message bodies are stored outside of
> the database. So in general, you shouldn't have BLOBs or
> multi-megabyte TEXT fields.
> 
> >2) After converting my test database to utf8mb4, and setting
> >mysql_charset = utf8mb4 in config.ini, the bug still persists, I got
> >precisely the same error message. Where does this utf8mb3_bin is come
> >from?... I even reinitalised the database with roundup-admin, with
> >no success.
> >
> >After doing a roundup-admin initialise with mysql_charset = utf8mb4,
> >mysql_dump showed lots of utf8mb3 databases, so its seems
> >mysql_charset had no effect. Strange.  
> 
> Indeed. I would expect that to have solved the problem.
> You are testing with 2.1.0 right? The changelog for 2.2.0 has:
> 
> - issue2551216 - create new mysql databases using COLLATE
>   utf8_general_ci to prevent crashes in test suite. (John Rouillard)
> 
> which was a no-op as far as I could tell with Python 3, but I may not
> have had the correct data in the db to trigger the issue. The patch
> for that change is:
> 
> diff -r eccb2f53566d -r 38e0fc1c7f11 roundup/backends/back_mysql.py
> --- a/roundup/backends/back_mysql.py    Tue Jul 05 19:45:12 2022 -0400
> +++ b/roundup/backends/back_mysql.py    Sun Jul 10 15:49:39 2022 -0400
> @@ -92,7 +92,7 @@
>      kwargs = connection_dict(config)
>      conn = MySQLdb.connect(**kwargs)
>      cursor = conn.cursor()
> -    command = "CREATE DATABASE %s"%config.RDBMS_NAME
> +    command = "CREATE DATABASE %s COLLATE
> utf8_general_ci"%config.RDBMS_NAME if sys.version_info[0] > 2:
>          command += ' CHARACTER SET utf8'
>      logging.info(command)
> 
> Maybe try making this change and re-test? Also I note that the
> hardcoded 'CHARACTER SET utf8' you mention below is seen in this diff.
> 
> >First I thought there are some problems in my
> >mariadb .cnf files, but I found some strange hardcoded lines in
> >backends/back_mysql.py:
> >
> >In db_create():
> >    if sys.version_info[0] > 2:
> >        command += ' CHARACTER SET utf8'
> >
> >In class MysqlClass:
> >    case_sensitive_equal = 'COLLATE utf8_bin ='  
> 
> Try changing the character set to use utf8mb4 and see if that
> helps. Running 'python3 -m pytest test/test_mysql.py' should turn up
> any major issues I hope.
> 
> My best guess is that you are onto something with
> 
>     case_sensitive_equal = 'COLLATE utf8_bin ='
> 
> The file rdbms_common.py sets
> 
>     case_sensitive_equal = '='
> 
> and uses that property in queries in _filter_sql for exact match if I
> understand the code correctly. This matches your observations about it
> only happening with exact match.
> 
> Ralf wrote that code so he would know if I am misinterpreting it
> incorrectly. There is a "utf8mb4_bin" collation. Maybe try changing
> 'utf8_bin' for 'utf8mb4_bin' see if it gets rid of the utf8mb3
> failure.
> 
> Maybe:
> 
>    https://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci
> 
> will help? It seems to indicate that utf8mb4_unicode_ci or
> utf8mb4_general_ci are possible replacements for utf8_general_ci.
> 
>   https://forums.mysql.com/read.php?103,187048,188748#msg-188748
> 
> and the stackoverflow answer seem to indicate that my utf8_general_ci
> should be replaced by utf8_unicode_ci and I assume the same would be
> true for utf8mb4.
> 
> We don't target/recommend a specific version of MySQL/MariaDB. However
> MySQL 8.0 (with utf8mb4* collations IIUC) has been out since 2016, so
> more than the 5 years of support given my most LTS Linux releases. If
> the utf8mb4 variants work for you, we can consider requiring mysql >
> 8.0 for the 2.4.0 release next year.
> 
> The test suite could use some help from somebody who understands
> unicode better than I do and can create a test that sorts differently
> between utf8[mb4]_general_ci and utf8[mb4]_unicode_ci.
> 
> 
> --
> 				-- rouilj
> John Rouillard
> ===========================================================================
> My employers don't acknowledge my existence much less my opinions.


_______________________________________________
Roundup-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/roundup-users
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.