How to connect Mysql server via Flask use Python? - python

I have trouble to connect mysql server via Flask.
I have 4 files: server.py ,testDB.py,testDB2.py and init.py
First , if init.py import testDB.py and I run python server.py, it will print
changes in the database
* Running on http://0.0.0.0:8000/ (Press CTRL+C to quit)
My user_info table will have user1.
However ,if init.py import testDB2.py and I run python server.py,it just print
* Running on http://0.0.0.0:8000/ (Press CTRL+C to quit)
My user_info table will not appear user2.
How do I solve this problem ?
The difference between testDb.py and testDB2.py is I defined a function in testDB2.py
init.py
from flask import Flask
app = Flask(__name__)
import testDB
server.py
from Sw import app
if __name__ == '__main__':
port = 8000
host = '0.0.0.0'
app.run(host = host, port = port)
testDB.py
import MySQLdb
db = MySQLdb.connect(host="127.0.0.1",user="root",passwd="1234",db="testdb")
cursor = db.cursor()
sql="""INSERT INTO user_info (user_id, user_email, user_password) VALUES ('user1','00000','000000')"""
try:
# Execute the SQL command
cursor.execute(sql)
# Commit your changes in the database
print "changes in the database"
db.commit()
except:
# Rollback in case there is any error
print "there is any error"
db.rollback()
db.close()
testDB2.py
import MySQLdb
def testDB():
db = MySQLdb.connect(host="127.0.0.1",user="root",passwd="1234",db="testdb")
cursor = db.cursor()
sql="""INSERT INTO user_info (user_id, user_email, user_password) VALUES ('user2','00000','000000')"""
try:
# Execute the SQL command
cursor.execute(sql)
# Commit your changes in the database
print "changes in the database"
db.commit()
except:
# Rollback in case there is any error
print "there is any error"
db.rollback()
db.close()

Just as #dirn said in the comment, the reason the database isn't updated in the second case is because you've defined a function, but then never made use of it. Just as any other function in Python, it waits for another line of code to call it into action. When you import it into your init.py file, you have two ways of running it. You can modify init.py like this:
from flask import Flask
app = Flask(__name__)
import testDB2
testDB2.testDB()
Which then runs your function from the init.py file, or you can modify testDB2.py and run the function from there, just by adding testDB() to the end of that file (outside the function, of course).

Related

Flask: db is not being referenced properly when importing into my database seeder script

# project\__init__.py
from flask import Flask
from flask_mysqldb import MySQL
from .config import app_config
db = MySQL()
def create_app(config_name):
app = Flask(__name__,
instance_path=os.path.join(os.path.dirname(__file__), 'instance'),
instance_relative_config=True)
app.config.from_object(app_config[config_name])
db.init_app(app)
print(db) # prints <flask_mysqldb.MySQL object at 0x000002A13710FC10>
# project/main.py
from . import db
#main.route('/foobar')
def foobar():
print(db) # prints <flask_mysqldb.MySQL object at 0x000002A13710FC10>
# project/database/seed_shipment.py
from project import create_app, db
def foo():
.
.
.
def goo()
.
.
.
if __name__ == '__main__':
config_name = os.getenv('FLASK_ENV')
app = create_app(config_name)
cursor = db.connection.cursor()
print(db) # prints <flask_mysqldb.MySQL object at 0x000002056B4EFD60>
print(db.connection) # returns None
for x in range(20):
# code which generates dummy data using foo() and goo()
cursor.execute("INSERT INTO shipment (column1, column2) VALUES (%s)", (var1, var2))
db.connection.commit()
My database connection works fine when I host the app and carry out CRUD operations using the interface in my browser. Such as login, sign up, create a shipment.
Note that I am not executing flask run from my terminal but instead python -m project.run, here is the code of this script:
# project/run.py
import os
from . import create_app
config_name = os.getenv('FLASK_ENV')
app = create_app(config_name)
if __name__ == '__main__':
app.run()
However, when I run python -m project.database.seed_shipment db seems to reference a different MySQL instance which has no connection. See the print results in the comments in my code.
My database connection works fine when I host the app and carry out CRUD operations using the interface in my browser. Such as login, sign up, create a shipment.
This indicates to me that you are correctly connecting to your db for each request.
However, when I run python -m project.database.seed_shipment db seems to reference a different MySQL instance which has no connection. See the print results in the comments in my code.
This, on the other hand, indicates to me that you are not connecting to your db when you directly execute seed_shipment - in fact, you seem to reference something different (as you write). In other words, db = MySQL() is not called.
I recommend that you try the following.
# project\__init__.py
from flask import Flask, g
from flask_mysqldb import MySQL
from .config import app_config
def create_app(config_name):
app = Flask(__name__,
instance_path=os.path.join(os.path.dirname(__file__), 'instance'),
instance_relative_config=True)
app.config.from_object(app_config[config_name])
# this here is just to register the teardown context and some variables ....
MySQL(app)
return app
def get_db():
if 'db' not in g:
g.db = MySQL().connection.cursor()
return g.db
That way, MySQL(app) is always executed when you call create_app. Now, you should be able to simply call get_db each time you want your db.

Unable to copy data into AWS RedShift

I tried a lot however I am unable to copy data available as json file in S3 bucket(I have read only access to the bucket) to Redshift table using python boto3. Below is the python code which I am using to copy the data. Using the same code I was able to create the tables in which I am trying to copy.
import configparser
import psycopg2
from sql_queries import create_table_queries, drop_table_queries
def drop_tables(cur, conn):
for query in drop_table_queries:
cur.execute(query)
conn.commit()
def create_tables(cur, conn):
for query in create_table_queries:
cur.execute(query)
conn.commit()
def main():
try:
config = configparser.ConfigParser()
config.read('dwh.cfg')
# conn = psycopg2.connect("host={} dbname={} user={} password={} port={}".format(*config['CLUSTER'].values()))
conn = psycopg2.connect(
host=config.get('CLUSTER', 'HOST'),
database=config.get('CLUSTER', 'DB_NAME'),
user=config.get('CLUSTER', 'DB_USER'),
password=config.get('CLUSTER', 'DB_PASSWORD'),
port=config.get('CLUSTER', 'DB_PORT')
)
cur = conn.cursor()
#drop_tables(cur, conn)
#create_tables(cur, conn)
qry = """copy DWH_STAGE_SONGS_TBL
from 's3://udacity-dend/song-data/A/A/A/TRAAACN128F9355673.json'
iam_role 'arn:aws:iam::xxxxxxx:role/MyRedShiftRole'
format as json 'auto';"""
print(qry)
cur.execute(qry)
# execute a statement
# print('PostgreSQL database version:')
# cur.execute('SELECT version()')
#
# # display the PostgreSQL database server version
# db_version = cur.fetchone()
# print(db_version)
print("Executed successfully")
cur.close()
conn.close()
# close the communication with the PostgreSQL
except Exception as error:
print("Error while processing")
print(error)
if __name__ == "__main__":
main()
I don't see any error in the Pycharm console but I see Aborted status in the redshift query console. I don't see any reason why it has been aborted(or I don't know where to look for that)
Other thing that I have noticed is when I run the copy statement in Redshift query editor , it runs fine and data gets moved into the table. I tried to delete and recreate the cluster but no luck. I am not able to figure what I am doing wrong. Thank you
Quick read - it looks like you haven't committed the transaction and the COPY is rolled back when the connection closes. You need to either change the connection configuration to be in "autocommit" or add an explicit "commit()".

Dynamic data wont change in flask

I'm trying to make an API in flask, but when I load up the API and then change the data in the database and reload the page the data doesn't change unless I restart the program. How do I make it so when the program is running and I change the data in the database I'll see it when I refresh the API in the browser? Thanks in Advance.
Here's the code:
from flask import Flask, jsonify, request
import pymysql.cursors
connection = pymysql.connect(host='127.0.0.1',
user='root',
password='myroot',
db='test',
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor)
app = Flask(__name__)
#app.route('/', methods=['GET'])
def test():
with connection.cursor() as cursor:
connection.connect()
sql = "SELECT * FROM importantData"
cursor.execute(sql)
result = cursor.fetchall()
return jsonify(result)
#app.route('/locations', methods=['GET'])
def test1():
with connection.cursor() as cursor:
connection.connect()
sql = "SELECT * FROM locations"
cursor.execute(sql)
result = cursor.fetchall()
return jsonify(result)
if __name__ == '__main__':
app.run(port=8080)
EDIT:
The solution was that I had to open the database connection in every route function, edited the code so now it works as it's supposed to.
I have never used pymysql, and your code looks fine except that part:
result = cursor.fetchone()
Why fetchone() when you are clearly select * selecting everything? What do you mean by I change data in database, did you change a row, or did you insert a new row?
In anycase, looks like you are selecting only the first row with fetchone(), so even if you changed something else, or if you added a new row, you will never see the new modifications
The solution was that I had to open the database connection in every route function, edited the code so now it works as it's supposed to

python connection to DB throwing error

I am new to using python to connect to a mysql DB and I am getting the following error:
OperationalError: (pymysql.err.OperationalError) (1045, u"Access denied for user 'xxxxxxadmin'#'xx.xx.xx.xx' (using password: YES)") (Background on this error at: http://sqlalche.me/e/e3q8)
xx.xxx.216.44 - - [02/Apr/2018 17:27:49] "GET /testconnect HTTP/1.1" 500 -
This is most of the connect script in my python file:
#!/usr/bin/python3
from flask import Flask, request
from flask_restful import Resource, Api
from sqlalchemy import create_engine
from json import dumps
from flask.ext.jsonpify import jsonify
db_connect = create_engine("mysql+pymysql://xxxxxxxadmin:password#,mymaindb.xxxxxxxx.us-east-2.rds.amazonaws.com:3306/myDBname")
app = Flask(__name__)
api = Api(app)
class TestConnect(Resource):
def get(self):
conn = db_connect.connect() # connect to database
query = conn.execute("select * from Players") # This line performs query and returns json result
return {'employees': [i[0] for i in query.cursor.fetchall()]} # Fetches first column that is Employee ID
api.add_resource(TestConnect, '/testconnect') # Route_1
if __name__ == '__main__':
app.run(host='0.0.0.0', debug = False)
Other background:
But when I try to connect to the same mysql database using the exact same credentials via the command line on the server running the python script I am able to get in.
Not sure how to test more to get a better error result that will help me figure this issue out.
UPDATE
So I was able to connect to my DB via mysql workbench with the connection strings and information I have in the python script. Does this mean my python script is doing something wrong?
Why not use:
mysql+pymysql://xxxxxxxadmin:password#mymaindb.xxxxxxxx.us-east-2.rds.amazonaws.com:3306/myDBname
instead of
mysql+pymysql://xxxxxxxadmin:password#**,**mymaindb.xxxxxxxx.us-east-2.rds.amazonaws.com:3306/myDBname
Not sure why you're connection string has a comma. Might just be a typo?
On that note, I usually build the connection URL before passing it to create_engine just to make it easier to manage in the future incase I have to pull the actual values from the environmental variables:
HOST = "mymaindb.xxxxxxxx.us-east-2.rds.amazonaws.com"
PORT = 3306
USERNAME = "xxxxxxxadmin"
PASSWORD = "password"
DBNAME = "myDBname"
CONNECTION_URL = 'mysql+pymysql://%s:%s#%s:%s/%s' % (
USERNAME,
PASSWORD,
HOST,
PORT,
DBNAME
)

raspberry pi sending data to a XAMPP database

I have the following code in python for sending data to a mysql database
import time
import datetime
import MySQLdb
from time import strftime
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
PIR_PIN = 21
GPIO.setup(PIR_PIN, GPIO.IN)
# Variables for MySQL
db = MySQLdb.connect(host="*******", user="root",passwd="*****", db="sensor1")
cur = db.cursor()
while True:
i = GPIO.input(PIR_PIN)
print i
datetimeWrite = (time.strftime("%Y-%m-%d ") + time.strftime("%H:%M:%S"))
print datetimeWrite
sql = ("""INSERT INTO templog (datetime,temperature) VALUES (%s,%s)""",(datetimeWrite,i))
try:
print "Writing to database..."
# Execute the SQL command
cur.execute(*sql)
# Commit your changes in the database
db.commit()
print "Write Complete"
except:
# Rollback in case there is any error
db.rollback()
print "Failed writing to database"
cur.close()
db.close()
break
My problem is that my XAMPP server is installed in pc where I want to view the the data from raspberry pi in mysql database.
So for getting the connection established what should I write in host= "?"
The connection-string should be like this:
db = MySQLdb.connect(host="192.168.0.xxx", user="root",passwd="*****", db="sensor1")
See this Question
Host will be IP address of your system on which XAMPP is installed e.g. 192.168.x.x

Categories

Resources