1
votes

I've inherited an application making use of python & sqlalchemy to interact with a mysql database. When I issue:

mysql_engine = sqlalchemy.create_engine('mysql://uname:[email protected]:3306/testdb', connect_args={'use_unicode':True,'charset':'utf8', 'init_command':'SET NAMES UTF8'}, poolclass=NullPool)

, at startup, an exception is thrown:

cmd = unicode("USE testdb")    
with mysql_engine.begin() as conn:
      conn.execute(cmd)

sqlalchemy.exc.OperationalError: (OperationalError) (2003, "Can't connect to MySQL server on '192.168.xx.xx' (101)") None None

However, using IDLE I can do:

>>> import MySQLdb
>>> Con = MySQLdb.Connect(host="192.168.xx.xx", port=3306, user="uname", passwd="pwd", db="testdb")
>>> Cursor = Con.cursor()
>>> sql = "USE testdb"
>>> Cursor.execute(sql)

The application at this point defaults to using an onboard sqlite database. After this I can quite happily switch to the MySQL database using the create_engine statement above. However, on reboot the MySQL database connection will fail again, defaulting to the onboard sqlite db, etc, etc.

Has anyone got any suggestions as to how this could be happening?

Just thought I would update this - the problem still occurs exactly as described above. I've updated the app so that the user can manually connect to the MySQL db by selecting a menu option. This calls the identical code which exceptions when the app is starting, but works just fine once the app is up and running.

The MySQL instance is completely separate from the app and running throughout, so it should be available to receive connections at all times.

I guess the fundamental question i'm grappling with is how can the same connect code work when the app is up and running, but throw an exception when it is starting?

Is there any artifact of SQLAlchemy that can cause it to fail to create usable connections that isn't dependant on the connection parameters or the remote database?

1
What do you mean Python dies? Exception? Segfault? No output? - univerio
@univerio - sorry, I didn't really provide enough info there - an exception is raised, I've added some more detail... - RadioRaheem

1 Answers

0
votes

Ahhh, it all seems so obvious now...

The reason for the exception on startup was because the network interface hadn't finished configuring when the application would make its first request to the remote database. (Which is why the same thing would be successful when attempted at a later time).

As communication with the remote database is a prerequisite for the application, I now do something like this:

if grep -Fxq "mysql" /path/to/my/db/config.config
then
    while ! ip a | grep inet.*wlan0 ; do sleep 1; echo "waiting for network..."; done;
fi

... in the startup script for my application - ensuring that the network interface has finished configuring before the application can run.

Of course, the application will never run if the interface doesn't configure, so it still needs some finessing to allow it to timeout and default to using a local database...