changeset 8589:7b0aafc6b7ca

mysql: create database with explicit UTF-8 character set and collation A spin-off from Issue #378. In MySQL, the character sets for server, database, tables, and connection are set independently. Ideally, they should all use UTF-8, but systems tend to use latin1 as default encoding, for example: character_set_server = latin1 collation_server = latin1_swedish_ci Databases would thus by default be created as: character_set_database = latin1 collation_database = latin1_swedish_ci To make things work consistently anyway, we have so far specified the utf8mb4 charset explicitly when creating tables, but there is no corresponding simple option for specifying the collation for tables. We need a better solution. If necessary and possible, the system charset and collation should be set to UTF-8. Some systems already have these defaults default - see https://mariadb.com/kb/en/differences-in-mariadb-in-debian-and-ubuntu/ . The defaults can be changed as described on https://mariadb.com/kb/en/setting-character-sets-and-collations/#example-changing-the-default-character-set-to-utf-8 to give something like: character_set_server = utf8mb4 collation_server = utf8mb4_unicode_ci Databases will then by default be created as: character_set_database = utf8mb4 collation_database = utf8mb4_unicode_ci and there is thus no longer any need for specifying the charset when creating tables. To be reasonably resilient across all systems without relying on system defaults, we will now start specifying the charset and collation when creating the database, but drop the specification of charset when creating tables. For existing databases, it is recommended to change encoding (and collation) by altering the database and each of the tables inside it as described on https://stackoverflow.com/questions/6115612/how-to-convert-an-entire-mysql-database-characterset-and-collation-to-utf-8 . Note the use of utf8mb4_unicode_ci instead of utf8mb4_general_ci - see https://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci . For investigation of these issues, consider the output from: show variables like '%char%'; show variables like '%collation%'; show create database `KALLITHEA_DB_NAME`; SELECT * FROM information_schema.SCHEMATA WHERE schema_name = "KALLITHEA_DB_NAME"; SELECT * FROM information_schema.TABLES T, information_schema.COLLATION_CHARACTER_SET_APPLICABILITY CCSA WHERE CCSA.collation_name = T.table_collation AND T.table_schema = "KALLITHEA_DB_NAME";
author Mads Kiilerich <mads@kiilerich.com>
date Mon, 15 Jun 2020 17:27:19 +0200
parents 210e76d69b62
children e1f233b069b0
files kallithea/lib/db_manage.py kallithea/model/db.py
diffstat 2 files changed, 1 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/kallithea/lib/db_manage.py	Mon Jun 15 16:57:20 2020 +0200
+++ b/kallithea/lib/db_manage.py	Mon Jun 15 17:27:19 2020 +0200
@@ -97,7 +97,7 @@
                 engine = sqlalchemy.create_engine(url)
                 with engine.connect() as conn:
                     conn.execute('DROP DATABASE IF EXISTS `%s`' % database)
-                    conn.execute('CREATE DATABASE `%s`' % database)
+                    conn.execute('CREATE DATABASE `%s` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci' % database)
             elif url.drivername == 'postgresql':
                 from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
                 url.database = 'postgres'  # connect to the system database (as the real one might not exist)
--- a/kallithea/model/db.py	Mon Jun 15 16:57:20 2020 +0200
+++ b/kallithea/model/db.py	Mon Jun 15 17:27:19 2020 +0200
@@ -167,7 +167,6 @@
 
 _table_args_default_dict = {'extend_existing': True,
                             'mysql_engine': 'InnoDB',
-                            'mysql_charset': 'utf8mb4',
                             'sqlite_autoincrement': True,
                            }