Forums

sqlAlchemy connection issue

Trying to connect to my database but I keep getting the following error:

_mysql_exceptions.OperationalError: (1045, "Access denied for user 'mpm206'@'ip-10-63-166-201.ec2.internal' (using password: YES)")

I assume I'm making some kind of obvious mistake but I have no idea what:


from flask import Flask, abort, render_template, request, Response, redirect
from flask_bootstrap import Bootstrap
from flask.ext.sqlalchemy import SQLAlchemy
import SKapi, Spotify
import json, urllib.parse
from flask_wtf import Form
from wtforms import StringField, DateField
from wtforms.validators import DataRequired

# app instance
app = Flask(__name__)

# bootstrap instance
bootstrap = Bootstrap(app)

# configure app
app.config.from_object('config')

# mySQL
db = SQLAlchemy(app)

class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(100), unique=True, index=True)
    hash = db.Column(db.String(255))
    cplace = db.Column(db.String(100))
    cend = db.Column(db.String(10))
    cstart = db.Column(db.String(10))
    cpid = db.Column(db.Integer)
    events = db.relationship('Events', backref='user', cascade="all, delete-orphan")

    def __repr__(self):
        return '<User %r>' % self.username

class Events(db.Model):
    __tablename__ = 'saved'
    id = db.Column(db.Integer, primary_key=True)
    uid = db.Column(db.Integer, db.ForeignKey('users.id'))
    evtid = db.Column(db.Integer)
    artist = db.Column(db.String(255))
    venue = db.Column(db.String(100))
    addr = db.Column(db.String(255))
    date = db.Column(db.String(10))
    time = db.Column(db.String(40))
    link = db.Column(db.String(255))
    sample = db.Column(db.String(100))

Here's my config for the database with password substituted for the actual password.


SQLALCHEMY_DATABASE_URI = 'mysql://mpm206:password@mpm206.mysql.pythonanywhere-services.com/mpm206$bandflight'

Then I've just added this route to check the connection:

@app.route('/adduser')
     def adduser():
          new_user = User(username='mpm206', hash='password')
          db.session.add(new_user)
          db.session.commit()
          return 'Success'

Where am I going wrong?

the error sounds like it is trying to access the db without loading the db config stuff.

ie. the mpm206'@'ip-10-63-166-201.ec2.internal should be saying mpm206'@mpm206.mysql.pythonanywhere-services.com' if you had set it up correctly.

if you look at the error traceback, where is it trying to access the db? eg- is it at the bootstrap line? in that case you probably need to move that line below the db setup.

Yer, her's the traceback:

  2016-05-03 12:52:00,672 :Exception on /adduser [GET]
    Traceback (most recent call last):
     File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/pool.py", line 1044, in _do_get
      return self._pool.get(wait, self._timeout)
       File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/util/queue.py", line 145, in get
       raise Empty
    sqlalchemy.util.queue.Empty

I've tried adding SQLALCHEMY_POOL_RECYCLE = 280 to the config file, but no dice so far.

Your database name looks wrong. MySQL databases on PythonAnywhere are named like this: username$db_name. The databases that you've created and their names are listed on the Databases tab.

Nope, don't think that's wrong. Here's the line from the config file:

SQLALCHEMY_DATABASE_URI = 'mysql://mpm206:password@mpm206.mysql.pythonanywhere-services.com/mpm206$bandflight'

and here's the database name: mpm206$bandflight

You're right. I misread the connection string.

Have you tried connecting from a bash console like this?

mysql -h mpm206.mysql.pythonanywhere-services.com 'mpm206$bandflight'

and entering the password you're using to connect from your webapp?

If that doesn't work, you're using the wrong password. If it does work it may be that your config file isn't being processed somehow. CHeck that the values you set in the config file are actually set on the app when you try to connect to the database.

Right, I can connect just fine through the bash console, so it's not a password issue. As Conrad pointed out, it looks like there's something wrong with the config file. I'm beginning to suspect it may be that I'm running Python3.5, I may try migrating to 3.4, see if that helps.

Update: Couldn't get it working on pythonanywhere, but I got it working beautifully on my localhost with the config:

SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:password@localhost:3306/bandflight'

So it can definitely work with python 3.4, which I've now switched my app over to.

What could be causing it to mpm206'@'ip-10-63-166-201.ec2.internal instead of where I'm telling it to in the config file?

Right, it's working beautifully on my local machine, and the only difference is the SQLALCHEMY_DATABASE_URI is the only difference so that's all I can think that could be wrong. Any ideas what's going on?

So why is the error message reading:

denied for user 'mpm206'@'ip-10-181-77-114.ec2.internal'

just to clarify- so you can get it working on python anywhere using python3.4 but not python3.5? could it be some python libraries that are installed in python3.4 but not 3.5? are you using a virtualenv?

No, I have exactly the same set up with my own instance of MySQL on my laptop and I can make it work on my local machine if I use


 SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:password@localhost:3306/bandflight'

but when I try to repeat it on pythonanywhere with everything the same I get that error. I'm using python3.4 for both now, I'm not using a virtualenv.


The only difference between the copy on my localhost machine and that on the pythonanywhere server is the database_URI:

SQLALCHEMY_DATABASE_URI = 'mysql://mpm206:password@mpm206.mysql.pythonanywhere-services.com/mpm206$bandflight'

hmm. I just checked your webapp setup. It seems like you don't have the correct cname setup for your new webapp. I also double checked that from the web server that is running your code, you would be able to access mpm206.mysql.pythonanywhere-services.com. Are you sure you don't have a localhost in your code somewhere?

Yes, I had to change the Cname when I deleted the app to change from python 3.5 to 3.4 and it takes a bit of time to change over the DNS, so that's been changed to match now, it'll just take a little time to propagate.

As for the localhost thing, the only two places the host could be declared are in the main app file or in the config file, neither of which contain the LocalHost. Very confused as to what's going on here.

I think the first step is to determine whether your config is, in fact being applied to the app. The investigation goes in different directions depending on the answer to that question.

Fairly confident the config is being applied to the app because I only declare the username and password in the config file.

Using just the Python3.4 shell:


>>> from bandflight import db
>>> db.create_all()

Produces the same errors, ending in:


"Access denied for user 'mpm206'@'ip-10-168-122-144.ec2.internal' (using password: YES)"

So it must be getting the username from the config file.

Long shot, but is it possibily a version difference either between flask-sqlalchemy or the mysql driver (those are the main suspects, but others could be causing it) on your machine vs PythonAnywhere. Are you running in a virtualenv already? If you're not, it's pretty easy to setup. Then you can install the same versions of the libraries you depend on into your webapp as you have on your machine.

I've set up a virtual environment and still no dice, exactly the same issue. No idea where it's getting the 'mpm206'@'ip-10-168-122-144.ec2.internal' from.

I just saw an SO post where someone was having an issue that looks very close to yours. Their solution was to escape some characters in their password. Unfortunately, they don't say which characters need escaping. You might want to try reducing your MySQL password to only alpha-numeric characters and then one-by-one re-introduce any punctuation.

I just saw an SO post where someone was having an issue that looks very close to yours. Their solution was to escape some characters in their password. Unfortunately, they don't say which characters need escaping. You might want to try reducing your MySQL password to only alpha-numeric characters and then one-by-one re-introduce any punctuation.

Unfortunately right now it is plain text, purely alpha! This is very frustrating, I have to hand this in on Monday!

AHA! FINALLY FIXED IT! Not sure which of the two did it, probably the first but it could have been a combination of the two:

  1. I had a short password set (or at least I thought I did) that was actually too short to be a valid password. For some bizarre reason I didn't get a warning message when I set it so I thought it was all fine. Changed to a longer password and that's done the trick!

  2. I changed the " marks to backticks in the config file, suspect that might have something to do with it too.

Thanks so much for all your help and patience!

.

Aha! Glad you worked it out :-)