I have push a python-django project to heroku and it works well. In my view.py file of django model, I added function that could connect to the local mysql database to retrieve data from the mysql. The function is the view.py is as followed:
#login_required
def results(request):
data=[]
data1 = []
owner = request.user
owner = str(owner)
db = MySQLdb.connect(user='root', db='aaa', passwd='xxxxx', host='localhost')
cursor = db.cursor()
cursor.execute("SELECT search_content, id, title, author, institute, FROM result_split where username = '%s'" % (owner))
data = cursor.fetchall()
db.close()
return render(request, "webdevelop/results.html", {"datas": data})
But when I try to open the page that show the data from mysql database in the deployed heroku website, it show the error:"OperationalError at /results/
(2003, "Can't connect to MySQL server on 'localhost' ([Errno 111] Connection refused)")". How could I have this heroku project to connect to my local mysql database? Or I should choose alternative?
Firstly, you need to ensure that the user and password you're using to connect to MySQL is correct and that the user has the correct privileges to work with the selected database.
Then you can check that mysql is accepting connections on localhost.
As for directly addressing the Connection Refused exception, check things like the mysql socket used to communicate with localhost applications like your Django project. The socket must exist and be configured in MySQL.
I also recommend taking a look at something like SQLAlchemy for Python which will help you interact directly with the database using Python objects. For example,
Connecting to the database:
from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship, scoped_session, mapper
from config import DB_URL
"""Database Declaration"""
metadata = MetaData()
Base = declarative_base(name='Base', mapper=mapper, metadata=metadata)
engine = create_engine(DB_URL, pool_recycle=1800)
Session = sessionmaker(bind=engine, autocommit=False, autoflush=True)
session = scoped_session(Session)
You can now use session variable to perform queries and updates using its inherited functions from the SQLAlchemy Session class.
SQLAlchemy also includes a declarative model for telling Python what your tables look like. For example,
class Clinic(Base):
__tablename__ = 'clinic'
clinic_id = Column(Integer, primary_key=True)
clinic_name = Column(VARCHAR)
address = Column(VARCHAR)
city = Column(VARCHAR)
zip = Column(VARCHAR)
phone = Column(VARCHAR)
user_id = Column(VARCHAR)
These examples work well for my projects in Flask and should work well enough in Django.
Related
I am trying to create a FAST Api that is reading from an already existing table in PostgreSQL database but it is giving me an internal server error. Would appreciate your direction on what might be wrong with the code
The existing table looks like this:
schema : testSchema
table : test_api
id
email
1
test#***.com
2
test2#***.com
engine = sqlalchemy.create_engine("my_database_connection")
Base = declarative_base()
database = databases.Database("my_database_connection")
metadata = sqlalchemy.MetaData()
metadata.reflect(bind=engine, schema='testSchema')
test_api_tb = metadata.tables['testSchema.test_api']
class testAPI(Base):
__tablename__ = test_api_tb
id = Column(Integer, primary_key=True)
email = Column(String(256))
app = FastAPI()
#app.get("/testing_api/")
def read_users():
query = test_api_tb.select()
return database.execute(query)
The error I am getting from the logs
RecursionError: maximum recursion depth exceeded in comparison
The best thing you can do is to read the official documentation at fastapi.tiangolo.com, it is amazing and explains all the basics in a very detailed way.
SQL Relational Databases are used very often with FastAPI and are also mentioned in the documentation here, you can find step by step tutorial about how to use postgresql with sqlalchemy and FastAPI.
There are a few parts to make this work. The first part is to connect to the database:
engine = create_engine(my_database_connection)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
we create the engine with the connection string as you did, then we need to create a session in order to connect to the database. At the end we are creating a Base class which will help us to create the models and schemas.
Now we need to create the model using the base class just as you did above.
we need to make sure that the __tablename__ is the same as the name of the table in the database
class testAPIModel(Base):
__tablename__ = "test_api"
id = Column(Integer, primary_key=True)
email = Column(String(256))
Now comes the main part. We need to make sure we bind the engine of the database to the base class using
Base.metadata.create_all(bind=engine)
Now we will create a function that will help us and create a db session instance and will close the connection when we done with the query.
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
Now we can create the FastAPI app instance and get the data from the database.
#app.get("/testing_api/")
def read_users(db:Session = Depends(get_db)):
users = db.query(testAPIModel).all()
return users
We are using the Depends(get_db) to inject the db session from the function we wrote above.
The full code:
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, Session
from fastapi import Depends, FastAPI
from sqlalchemy import Column, Integer, String
my_database_connection = "postgresql://user:password#server_ip/db_name"
engine = create_engine(my_database_connection)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
class testAPIModel(Base):
__tablename__ = "test_api"
id = Column(Integer, primary_key=True)
email = Column(String(256))
Base.metadata.create_all(bind=engine)
app = FastAPI()
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
#app.get("/testing_api/")
def read_users(db:Session = Depends(get_db)):
users = db.query(testAPIModel).all()
return users
Good Luck!
I'm creating a in-memory database with python and I want to use SQLAlchemy with it.
All my application is currently working directly with queries to the db.
I've seen multiple ways of connecting but none of it is working. My current attempt stands as:
# Creates an sqlite database in memory
db = Database(filename=':memory:', schema='schema.sql')
db.recreate()
# ORM
engine = create_engine('sqlite:///:memory:')
Base = automap_base()
Base.prepare(engine, reflect=True)
User = Base.classes.user
session = Session(engine)
This gives AttributeError: user. How do I properly connect my database to the SQLAlchemy?
from sqlalchemy import create_engine
from sqlalchemy.orm import registry, Session
engine = create_engine("sqlite+pysqlite:///:memory:", echo=True, future=True)
session = Session(engine)
registry().metadata.create_all(engine)
ATTACH is your friend.
You can attach an in-memory database to the current database session.
E.g.,
db.init('sqlite://')
db.execute("ATTACH DATABASE ':memory:' AS my_database")
db.create_all()
I'm trying to create a mysql database using sqlalchemy.
I have a flask web app which contains an sqlite database. I'm trying to switch over to mysql. I'm fairly new to sqlalchemy and have learned how to create databases via sqlalchemy. However the databases were sqlite databases. I'm trying to use sqlalchemy to create a mysql database and after reading multiple posts i still can't seem to get it.
I've also installed python-mysqldb
Snippets of the original code used to create an sqlite database which was successful.
Base = declarative_base()
class Categories(Base):
__tablename__ = 'categories'
id = Column(Integer, primary_key=True)
name = Column(String, unique=True)
image = Column(String)
link = Column(String)
description = Column(String)
if __name__ =='__main__':
engine = create_engine('sqlite:///app/database/main.db', echo=True)
Base.metadata.create_all(engine)
mysql attempt
if __name__ =='__main__':
engine = create_engine('mysql://user:password#localhost/app/database/main.db', echo=True)
Base.metadata.create_all(engine)
mysql 2nd attempt
if __name__ =='__main__':
engine = create_engine('mysql://user:password#localhost/app/database/main.db', echo=True)
engine.execute("CREATE DATABASE main.db")
engine.execute("USE main.db")
The error i keep receiving.
sqlalchemy.exc.OperationalError: (_mysql_exceptions.OperationalError) (1049, "Unknown database 'app/database/main.db'") (Background on this error at: http://sqlalche.me/e/e3q8)
My best guess is that there's clearly something i'm missing about using mysql with sqlalchemy.
Any help to even point me in the right direction would be greatly appreciated.
a) The correct DBURI syntax for mysql is:
mysql://username:password#servername/databasename
b) The database databasename must be created first. So before you run the Python .create_all() you should connect to the db server using the command line mysql client and execute the CREATE DATABASE databasename statement to create an empty database:
$ mysql -u username -p
... type password
> CREATE DATABASE databasename;
c) You should now be able to run the Python code to create the tables in the empty database.
I have a web application that is on top of mysql. When I started it, I built the mysql database from scratch, and connected to it using pymysql.
Fast forward...
I've rewritten everything using sqlalchemy to connect to the db (non-declarative?) I can connect to the db, read the db, update, etc. I also use MySQLWorkbench to view the database in a graphic way.
My webapp has a few tables that will poll the database for changes, and update the table. For instance, I have a job queue which will update the percentage-done. Here's the kicker:
When I send a job through, I will watch the database in MySQLWorkbench. I can verify that the job is going through (I see the percentage climbing). This confirms that the webapp is writing to the database. But! On the other end, where the table is asking for the status, it is not recieving the updated information (I've done print outs in the models, as well as in the flask app, as well as the FE js).
What is going on here? Even though I can see it in MySQLWorkbench is the connection not 'releasing' or something? Here is some of my code:
#models.py
from sqlalchemy.ext.automap import automap_base
from sqlalchemy.orm import Session
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker, Query
import os
import json
Base = automap_base()
engine = create_engine("mysql+pymysql://user:asdas758ef10d2364d54d7e8#localhost:{}/metadatacontroller".format(3306))
# reflect the tables
Base.prepare(engine, reflect=True)
EncodeQueue = Base.classes.encode_queue
db_session = scoped_session(sessionmaker(bind=engine))
class DataStore:
def __init__(self):
self.db = db_session()
#receive status
def queue_rendering_items(self):
query = self.db.query(EncodeQueue).filter(EncodeQueue.status.in_(['queue', 'rendering', 'rendering thumbnails'])).all()
return_query = []
for item in query:
row = {'artist_id': item.artist_id,
'art_id': item.art_id,
'status': item.status,
'progress': item.errors,
'artwork_title': item.artwork_title,
'artist_name': item.artist_name,
}
return_query.append(row)
return return_query
#update status
def update_render_progress(self, job_id, progress):
self.db.query(EncodeQueue).filter_by(job_id=job_id).update\({'errors': json.dumps(progress)})
self.db.commit()
(ignore the back slash in update_render_progress ... weird SO formatting)
This is how 'status' code is being called on a flask end point:
#app.route('/api/jobs', methods=["GET"])
def get_all_jobs():
db = models.DataStore()
all_art = db.queue_rendering_items()
print(all_art)
return jsonify({'data':all_art})
Lastly, the status is being updated by a different file, on a different machine:
import models
db = models.DataStore()
db.update_render_progress(job_id, {'percentage': percentage_complete, 'time_remain': render.render_estimated_seconds_remaining})
What the heck is happening?
I am trying out sqlalchemy and i am using this connection string to connect to my databases
engine = create_engine('sqlite:///C:\\sqlitedbs\\database.db')
Does sqlalchemy create an sqlite database for you if one is not already present in a directory it was supposed to fetch the database file?.
Yes,sqlalchemy does create a database for you.I confirmed it on windows using this code
from sqlalchemy import create_engine, ForeignKey
from sqlalchemy import Column, Date, Integer, String
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('sqlite:///C:\\sqlitedbs\\school.db', echo=True)
Base = declarative_base()
class School(Base):
__tablename__ = "woot"
id = Column(Integer, primary_key=True)
name = Column(String)
def __init__(self, name):
self.name = name
Base.metadata.create_all(engine)
As others have posted, SQLAlchemy will do this automatically. I encountered this error, however, when I didn't use enough slashes!
I used SQLALCHEMY_DATABASE_URI="sqlite:///path/to/file.db" when I should have used four slashes: SQLALCHEMY_DATABASE_URI="sqlite:////path/to/file.db"
Linux stored SQLite3 database
database will be create in the same folder as the .py file:
engine = create_engine('sqlite:///school.db', echo=True)
will instantiate the school.db file in the same folder as the .py file.
I found (using sqlite+pysqlite) that if the directory exists, it will create it, but if the directory does not exist it throws an exception:
OperationalError: (sqlite3.OperationalError) unable to open database file
My workaround is to do this, although it feels nasty:
if connection_string.startswith('sqlite'):
db_file = re.sub("sqlite.*:///", "", connection_string)
os.makedirs(os.path.dirname(db_file), exist_ok=True)
self.engine = sqlalchemy.create_engine(connection_string)
#Gandolf's answer was good.
The database is created it when you make any connection with your engine.
Here's an example of doing nothing with a database besides connecting to it, and this will create the database.
from sqlalchemy import create_engine
engine = create_engine('sqlite:///database.db')
with engine.connect() as conn:
pass
Without the engine.connect() or some form of metadata.create_all() the database will not be ceated.