Opened 16 years ago

Closed 4 years ago

#6517 closed Bug (fixed)

MySQL: manage.py dbshell does not get charset from DATABASES setting

Reported by: Tom Vergote Owned by: Manav Agarwal
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords:
Cc: julie@…, victoria@… Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description

I noticed that manage.py dbshell doesn't respect the database_options.
I ran into an issue with an application we are creating that needs to support mysql and postgre at least, we execute some sql scripts that get piped to manage.py dbshell (to avoid hardcoding psql -U xxx or mysql -u xxx and creating 2 scripts every time).

When running an utf8 database with utf8 as our charset in database_options, we ran into some weird encoding issues.

The solution for us was to learn mysql/client.py to respect the encoding settings in settings.py

Are you opposed to something like this?

Attaching small patch that fixes our problem. Let me know if it needs extending to support other backends or database_options.

Attachments (1)

mysql_client.patch (776 bytes ) - added by Tom Vergote 16 years ago.
small patch to illustrate suggestion

Download all attachments as: .zip

Change History (19)

by Tom Vergote, 16 years ago

Attachment: mysql_client.patch added

small patch to illustrate suggestion

comment:1 by Tom Vergote, 16 years ago

Has patch: set

Also please note that the read_default_file setting is respected, so it's somehow inconsistent behaviour

comment:2 by Tom Vergote, 16 years ago

Summary: manage.py dbshell doesn't respect database_optionsmanage.py dbshell does not get charset from database_options

comment:3 by Simon Greenhill <dev@…>, 16 years ago

Triage Stage: UnreviewedDesign decision needed

comment:4 by Julien Phalip, 13 years ago

Needs tests: set
Severity: Normal
Type: Bug

comment:5 by Carl Meyer, 13 years ago

Easy pickings: unset
Triage Stage: Design decision neededAccepted
UI/UX: unset

We should look into whether this is needed on other backends as well, not just MySQL.

comment:6 by Julie Pichon, 12 years ago

Cc: julie@… added

I adapted tvrg's patch to the current codebase - https://github.com/jpichon/django/compare/ticket_6517

I also tested dbshell with the sqlite3 and postgresql backends, and it works with UTF-8 characters without patching.

There are other ways to get the MySQL backend to play nicely with UTF-8 that don't require changing the code. You can add "default-character-set = utf8" to /etc/mysql/my.cnf on the server side, or create an option file with the UTF-8 charset config and update the settings to point to it in the "read_default_file" database options (as seen on https://docs.djangoproject.com/en/dev/ref/databases/#connecting-to-the-database)

[client]
default-character-set = utf8

If the patch option is preferred, I'm happy to work on the tests if someone could let me know where the dbshell tests live.

comment:7 by Julie Pichon, 12 years ago

Triage Stage: AcceptedDesign decision needed

comment:8 by Anssi Kääriäinen, 11 years ago

Triage Stage: Design decision neededAccepted

Seems like a good idea to me.

comment:9 by Victoria Martínez de la Cruz, 9 years ago

Cc: victoria@… added
Owner: changed from nobody to Victoria Martínez de la Cruz
Status: newassigned

comment:10 by Tim Graham, 9 years ago

Summary: manage.py dbshell does not get charset from database_optionsMySQL: manage.py dbshell does not get charset from DATABASES setting

A tests can be added in tests/dbshell/test_mysql.py.

comment:11 by Tim Graham, 8 years ago

Owner: Victoria Martínez de la Cruz removed
Status: assignednew

comment:12 by Mariusz Felisiak, 4 years ago

Easy pickings: set

comment:13 by Manav Agarwal, 4 years ago

Owner: set to Manav Agarwal
Status: newassigned

comment:14 by Manav Agarwal, 4 years ago

I wrote a test which is as follows:

def test_charset_configured(self):
    self.assertEqual(
        ['mysql', '--user=someuser', '--password=somepassword',
         '--host=somehost', '--port=444', 'somedbname'],
        self.get_command_line_arguments({
            'NAME': 'somedbname',
            'USER': 'someuser',
            'PASSWORD': 'somepassword',
            'HOST': 'somehost',
            'PORT': 444,
            'DEFAULT-CHARACTER-SET': 'utf8',
            'OPTIONS': {},
        }))

So in the above-mentioned tests, it is working fine when I am not using --default-character-set=utf8 in the list while I am including the same in the dictionary. (The above test is working fine) but IMO it should not work fine as when we are explicitly defining default-character-set to utf8 in the settings file, then it is to be mentioned in the list but as soon as I am adding the same to the list it is raising an error which means it needs a patch and after applying the patch as follows:

charset = settings_dict['OPTIONS'].get('charset',settings_dict['DEFAULT-CHARACTER-SET'])
if charset:
    args += ["--default-character-set=%s" % charset]

The above test is getting failed and the below-mentioned test is getting successfully executed.

def test_charset_configured(self):
    self.assertEqual(
        ['mysql', '--user=someuser', '--password=somepassword',
         '--host=somehost', '--port=444', 'somedbname',  '--default-character-set=utf8'],
        self.get_command_line_arguments({
            'NAME': 'somedbname',
            'USER': 'someuser',
            'PASSWORD': 'somepassword',
            'HOST': 'somehost',
            'PORT': 444,
            'OPTIONS': {},
            'DEFAULT-CHARACTER-SET': 'utf8',
        }))

If the patch and the tests seem fine, I may create a PR

Last edited 4 years ago by Manav Agarwal (previous) (diff)

comment:15 by Mariusz Felisiak, 4 years ago

Needs tests: unset

comment:16 by Mariusz Felisiak, 4 years ago

Patch needs improvement: set

comment:17 by Mariusz Felisiak, 4 years ago

Patch needs improvement: unset
Triage Stage: AcceptedReady for checkin

comment:18 by Mariusz Felisiak <felisiak.mariusz@…>, 4 years ago

Resolution: fixed
Status: assignedclosed

In af87574a:

Fixed #6517 -- Made dbshell use charset option on MySQL.

Co-Authored-By: Mariusz Felisiak <felisiak.mariusz@…>

Note: See TracTickets for help on using tickets.
Back to Top