#30224: Mysql Datetime value is string instead of datetime object
-------------------------------------+-------------------------------------
     Reporter:  Martin Kuhn          |                    Owner:  Rohit Jha
         Type:  Bug                  |                   Status:  assigned
    Component:  Database layer       |                  Version:  dev
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:
     Keywords:  Mysql                |             Triage Stage:  Accepted
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

Comment (by Baptiste):

 I confirm that this issue is related to mysql, in my case with version 5.7

 Upgrading to MariaDB solved this issue. However, it can be tricky to do
 this kind of upgrade, so I'll give my feedback if it can help others that
 struggle to proceed to the upgrade.

 == Disclaimer/Environment
 **First and foremost, please take into consideration the following
 environment/context as I have NOT tested this process for other
 OS/version, so if you're not under this environment, you should proceed
 CAREFULLY and double-check steps! **
 - CentOS 7.5
 - MySQL version 5.7
 - Django 2.2.28
 - Python 3.6.9
 - pip 21.0.1

 == Prerequisites
 I suggest you first to put your server into maintenance. It depends on
 your WSGI application/webserver, but the goal here is to prevent any
 inbound HTTP connection to your server. In my case, I just configured a
 maintenance view from the NGINX server (we have a reverse proxy) in order
 to let the users know, and we just stopped all redirections to our
 gunicorn instances.

 Then :
 1. Stop mysql service
 {{{
 systemctl stop mysql
 }}}

 2. Take a backup of the databases (it will save all of your Django
 applications/projects if you have several). PS: For the sake of the
 example, I've stored it on /root but feel free to store anywhere you want,
 and also care to specify the root user of your mysql instance to get the
 dump.
 {{{
 cp -apf /var/lib/mysql /var/lib/mysql_backup
 cd /root/
 mysqldump --all-databases -u <your_user_goes_here> -p > all_databases.sql
 }}}

 3. Finally, remove all mysql packages
 {{{
 yum remove mysql-server mysql-client mysql-community-*
 }}}

 == Install MariaDB server 10.4
 4. You need to use the MariaDB official repositories for YUM
 {{{
 yum install wget
 wget https://downloads.mariadb.com/MariaDB/mariadb_repo_setup
 chmod +x mariadb_repo_setup
 sudo ./mariadb_repo_setup
 }}}

 5. Before you can install MariaDB, you may need to cleanup your ius and
 epel releases repos in your server (in my case, I had to, otherwise it
 would generate errors during installing MariaDB). If you feel you can skip
 this step, go ahead, you can go back to this step if needed.
 {{{
 yum erase ius-release
 rm /etc/yum.repos.d/ius*.repo*
 yum install https://repo.ius.io/ius-release-el7.rpm
 https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
 }}}

 6. Then, install all the packages required for Django to work with MariaDB
 (MariaDB-devel was required in my case, otherwise some libraries were
 missing for Django to work)
 {{{
 yum install MariaDB-server MariaDB-client MariaDB-devel
 }}}

 7. Start the MariaDB services afterwards
 {{{
 systemctl start mariadb
 systemctl enable mariadb
 }}}

 == Proceed to migration
 Welcome to the tricky steps! Good luck...

 8. You should start by using the MariaDB's command to upgrade the
 database. If you get no errors, good for you.. :)
 {{{
 mariadb-upgrade -u <your_db_user> -p
 }}}

 9. If errors appeared at some steps, you can always try to add the --force
 flag as per suggested by MariaDB:
 {{{
 mariadb-upgrade -u <your_db_user> -p --force
 }}}

 10. If you had no luck with some tables using JSON data type, you may
 encounter {{{ Unknown data type "MYSQL_JSON" }}} errors when selecting
 data in your DB. Then you need to manually fix all the tables with that
 JSON type columns. First, you need to stop the MariaDB instance
 {{{
 systemctl stop mariadb
 }}}

 11. Then, open a new mysql instance with the following settings (in my
 case, datadir was {{{/var/lib/mysql/}}} and plugin-dir was
 {{{/usr/lib64/mysql/plugin}}})
 {{{
 mysqld --no-defaults --datadir=<Your data dir directory> --lc-
 messages_dir=./share --plugin-dir=<path to directory containing
 type_mysql_json.so> --plugin-maturity=alpha -u <your_sql_user>
 }}}

 12. On another terminal, you can then install the mysql_json plugin and
 fix the tables with
 {{{
 install soname 'type_mysql_json';
 ALTER TABLE `database_name`.`table_name` FORCE;
 }}}

 13. You can also use this command if you have lots of tables with JSON
 type columns
 {{{
 SELECT CONCAT("ALTER TABLE `", TABLE_SCHEMA,"`.`", TABLE_NAME, "` FORCE;")
 AS MySQLCMD FROM TABLES WHERE TABLE_SCHEMA = "<YOUR_DATABASE_NAME>";
 }}}

 14. If this, still, does not fix all of your SELECT commands in your DB,
 you can also try to retrieve the dump directly:
 {{{
 mysql -u <your_db_user> -p < all_databases.sql
 }}}

 15. Don't forget to restart the MariaDB instance, if it was shutdown :)
 {{{
 systemctl start mariadb
 }}}

 == Testing & troubleshooting

 You should **deeply** test requests (read, create, update and delete) once
 everything seem to work again. You can, for instance:
 - Run random SELECT on several tables of your databases.
 - Start a Django instance
 - Dive deeply into your Django Admin, and do some CRUD operations from
 there

 Here a few bugs that I've encountered after the migration, if it helps:
 * **{{{Error loading MySQLdb module. Did you install mysqlclient?}}} when
 launching a Django instance**

 To solve this, I just had to reinstall mysql client from pip
 {{{
 pip install --force-reinstall --ignore-installed --no-binary :all:
 mysqlclient
 }}}

 * **{{{EnvironmentError: mysql_config not found}}} when launching a Django
 instance**
 Make sure that you have all the MariaDB yum required packages (especially
 the {{{MariaDB-devel}}} package)

 * **For no apparent reasons, some of the tables didn't recovered from the
 upgrade (Celery-related issue)**
 I have several django-celery-beat instances running, and for some, the
 periodic tasks did not recovered from the upgrade. I simply had to
 manually restore the tables from Celery (days after migration), and here
 some useful tricks if you want to recover from a previous SQL dump without
 erasing all your current and accurate data from other tables.

 1. From your SQL server, create a temp restore user and assign permissions
 on the only tables you'd want to restore
 {{{
 GRANT SELECT ON django_project.* TO 'admin_restore_temp'@'localhost'
 IDENTIFIED BY 'its_pwd';
 GRANT ALL ON django_project.table1 TO 'admin_restore_temp'@'localhost';
 }}}

 2. Restore the data (assuming you're getting a recover from
 {{{/data/backup/db1.sql}}} dump file)
 {{{
 mysql --user admin_restore_temp --password --force < /data/backup/db1.sql
 }}}

 3. Check that everything is okay, and don't forget to drop the temp user
 {{{
 DROP USER admin_restore_temp;
 }}}

 == Useful resources
 Hope these instructions can help you to migrate safely from mysql to
 MariaDB in order to workaround this issue. Here's some of the resources
 I've used:
 * [https://mariadb.com/fr/resources/blog/installing-mariadb-10-on-
 centos-7-rhel-7/]
 * [https://mariadb.com/kb/en/restoring-data-from-dump-files/]

 Good luck!

-- 
Ticket URL: <https://code.djangoproject.com/ticket/30224#comment:19>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/01070187aff4c467-7d6ef196-ff30-4a6c-aeb6-b0296f5e50a6-000000%40eu-central-1.amazonses.com.

Reply via email to