Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

connections.py read_default_group = "client" #811

Open
MrBenGriffin opened this issue Sep 12, 2019 · 8 comments
Open

connections.py read_default_group = "client" #811

MrBenGriffin opened this issue Sep 12, 2019 · 8 comments

Comments

@MrBenGriffin
Copy link

MrBenGriffin commented Sep 12, 2019

The [client] group does not normally include the database name, and including it will prevent mysqldump (and other services) from running.

Typically the database is set under the [mysql] group.

Without causing much trouble to existing code, the read_default_group switch could accept a tuple of groups (eg ('client','mysql'). However, the underlying configparser only allows a single default group. (Py2 ConfigParser doesn't allow one to set a default group, but one can set default values).

So, the default group should be 'client' and, following https://dev.mysql.com/doc/refman/8.0/en/option-files.html#option-file-syntax (and the way in which mysql cli works), and unless otherwise specified, the group should be '[pymysql]' (The application name), with the default group being [client].

@MrBenGriffin
Copy link
Author

Alternatively, the read_default_group could be additional to [client]

@methane
Copy link
Member

methane commented Mar 4, 2020

What is the behavior of the mysql cli and mysqlclient-python?
I will make them consistent as possible.

@MrBenGriffin
Copy link
Author

MrBenGriffin commented Mar 4, 2020

This is what I find. I will see what I can do to get documentation.
The [mysql] group is used for the specific mysql application.
The [client] group is used for any client-based connectivity.

So, the idea is to start off with the generic (client), and then overwrite/add changes as set in the specific (mysql) - but it may be a very good idea to add your own group too - eg [pymysql] - this would mean that the same config file could have specific switches for the PyMySQL connections.

This could also allow for a config file to make settings for pymysql implementation without having to amend the application sourcecode. (It's a good, old, principle not to mix data with code - but sql settings are an area where this rule of thumb often falls short).

The issue is especially relevant when using the same config file for, eg, mysqldump - which kicks up a fuss if there is a database setting in the client group.

The following would work fine, (bearing in mind that the programmer can always set the group to read as [mysql] - with the client being the fall-back for values not set in the primary group.

[pymysql]
database=my_database

[mysql]
database=my_database

[client]
user=mysql_user
password= mysql_password_1234
host=localhost
default-character-set=utf8

@MrBenGriffin
Copy link
Author

https://dev.mysql.com/doc/refman/8.0/en/option-files.html#option-file-syntax

If an option group name is the same as a program name, options in the group apply specifically to that program. For example, the [mysqld] and [mysql] groups apply to the mysqld server and the mysql client program, respectively.

The [client] option group is read by all client programs provided in MySQL distributions (but not by mysqld). To understand how third-party client programs that use the C API can use option files, see the C API documentation at Section 28.6.6.50, “mysql_options()”.

The [client] group enables you to specify options that apply to all clients. For example, [client] is the appropriate group to use to specify the password for connecting to the server. (But make sure that the option file is accessible only by yourself, so that other people cannot discover your password.) Be sure not to put an option in the [client] group unless it is recognized by all client programs that you use. Programs that do not understand the option quit after displaying an error message if you try to run them.

List more general option groups first and more specific groups later. For example, a [client] group is more general because it is read by all client programs, whereas a [mysqldump] group is read only by mysqldump. Options specified later override options specified earlier, so putting the option groups in the order [client], [mysqldump] enables mysqldump-specific options to override [client] options.

To create option groups to be read only by mysqld servers from specific MySQL release series, use groups with names of [mysqld-5.7], [mysqld-8.0], and so forth

@MrBenGriffin
Copy link
Author

MrBenGriffin commented Mar 4, 2020

So this is what I found.

https://dev.mysql.com/doc/refman/8.0/en/mysql-options.html
The documents say the following (my emphasis):

  • MYSQL_READ_DEFAULT_GROUP (argument type: char *)
    Read options from the named group from my.cnf or the file specified with MYSQL_READ_DEFAULT_FILE.

The client group is always read if you use MYSQL_READ_DEFAULT_FILE or MYSQL_READ_DEFAULT_GROUP.

My interpretation is that if I set a group [pymysql] via

pymysql.connect(...,read_default_group = "pymysql")

then the client group will also be read - and that this will be done when MYSQL_READ_DEFAULT_GROUP is called.

@MrBenGriffin
Copy link
Author

MrBenGriffin commented Mar 4, 2020

In connections.py, on line 220, the Parser() initialisation should include the default groups path which is converted into an OrderedDict called _defaults in the parser (cf. line 1154 of configparser.py) ; the init specifies a default_section argument of (on line 600 of configparser.py); this default_section is different from the default_group!

See the Pull Request #844 for a working solution

The default group (as supplied via read_default_group = "pymysql") is set (or overridden by the coder), and will be used as the topmost group, with the fallback as specified in the parser initialisation default_section (client).

configparser doesn't appear to allow for a chain of default sections, so it's not possible to accurately map the mysql client specifications allowing for client -> client-5.7 -> mysql -> mysql-5.6 -> pymysql etc, but supporting the 'client' group is definitely moving in the right direction.

@MrBenGriffin
Copy link
Author

MrBenGriffin commented Mar 4, 2020

Pull request #844

This now works with both PY2 and PY3, and is backwards compatible; it also includes tests to support default groups correctly.

@MrBenGriffin
Copy link
Author

I have also posted an issue on python ( https://bugs.python.org/issue39860 ) concerning cascading defaults. The pull request doesn't depend upon the issue being fixed in configparser, but it does support the fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants