3

I'm working on the front end of a webapp, and my co-developer is using Pyramid and SQAlchemy. We've just moved from SQLite to MySQL. I installed MySQL 5.6.15 (via Homebrew) on my OS X machine to get the Python MySQLdb install to work (via pip in a virtualenv).

Because in MySQL >= 5.6.5 secure_auth is now ON by default I can only connect to the remote database (pre 5.6.5) with the --skip-secure-auth flag, which works fine in a terminal.

However, in the Python Pyramid code, it only seems possible to add this flag as an argument to create_engine(), but I can't find create_engine() in my co-dev's code, only the connection string below in an initialisation config file. He's not available, this isn't my area of expertise, and we launch next week :(

sqlalchemy.url = mysql+mysqldb://gooddeeds:[email protected]/gooddeeds_development?charset=utf8

I've tried appending various "secure auth" strings to the above with no success. Am I looking in the wrong place? Has MySQLdb set secure_auth to ON because I'm running MySQL 5.6.15? If so, how can I change that?

2
  • 1
    Do you have the exact error message from the MySQL server? I'm not sure that secure_auth has much to do with it. If you still are using insecure, old-passwords (from pre-4.1), you you definitely have change that right now. Commented Feb 10, 2014 at 13:10
  • It was the well-known "Connection using old (pre-4.1.1) authentication protocol refused..." however, we can't make changes to MySQL on the server. I can log in on the command line with the --skip-secure-auth flag, which I admit should only be a temporary solution. For now, I need to do the same via SQLAlchemy. Commented Feb 11, 2014 at 12:10

1 Answer 1

3

If you are forced to use the old passwords (bah!) when using MySQL 5.6, and using MySQLdb with SQLAlchemy, you'll have to add the --skip-secure-auth to an option file and use URL:

from sqlalchemy.engine.url import URL

..

dialect_options = {
  'read_default_file': '/path/to/your/mysql.cnf',
}

engine = create_engine(URL(
  'mysql',
  username='..', password='..',
  host='..', database='..',
  query=dialect_options
  ))

The mysql.cnf would contain:

[client]
skip-secure-auth

For Pyramid, you can do the following. Add a line in your configuration ini-file that holds the connection arguments:

sqlalchemy.url = mysql://scott:tiger@localhost/test
sqlalchemy.connect_args = { 'read_default_file': '/path/to/foo' }

Now you need to change a bit the way the settings are read and used. In the file that launches your Pyramic app, do the following:

def main(global_config, **settings):
    try:
        settings['sqlalchemy.connect_args'] = eval(settings['sqlalchemy.connect_args'])
    except KeyError:
        settings['sqlalchemy.connect_args'] = {}
    engine = engine_from_config(settings, 'sqlalchemy.')
    # rest of code..

The trick is to evaluate the string in the ini file which contains a dictionary with the extra options for the SQLAlchemy dialect.

Sign up to request clarification or add additional context in comments.

2 Comments

How does this work in pyramid where we are using engine = engine_from_config(settings, 'sqlalchemy.')? - (co-developer)
I have updated my answer with a solution for Pyramid.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.