I am going to build a site using Flask+MySQL+Flask-SQLAlchemy, however, after reading some tutorials, I have some questions:
Flask-SQLAlchemy can be imported in at least two ways:
http://pythonhosted.org/Flask-SQLAlchemy/quickstart.html
from flask.ext.sqlalchemy import SQLAlchemy
OR http://flask.pocoo.org/docs/patterns/sqlalchemy/
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
The first way seems much more convenient. Why Pocoo team choose to use the second way?
http://pythonhosted.org/Flask-SQLAlchemy/queries.html The insert examples here are too simple. How can I perform INSERT
IGNORE or INNER JOIN? If I want to write native SQL statements. How to do that with SQLAlchemy?
I need some good examples on MySQL+Flask-SQLAlchemy, while most example are SQLite+MySQL+Flask-SQLAlchemy.
I have been coding using MySQL+Flask-SQLAlchemy and i host my applications on pythonanywhere.com ,like what #Sean Vieira said ,your code will run on any Relational database the only thing you need to change is the connection string to the database of your liking ,e.g using Mysql ,this will be saved in a file called config.py [you can save it using any other name]
SQLALCHEMY_DATABASE_URI = 'mysql://username:password#localhost/yourdatabase'
SQLALCHEMY_POOL_RECYCLE = 280
SQLALCHEMY_POOL_SIZE = 20
SQLALCHEMY_TRACK_MODIFICATIONS = True
then in your main app ,you will import it like this
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
# Create an Instance of Flask
application = Flask(__name__)
# Include config from config.py
application.config.from_object('config')
application.secret_key = 'some_secret_key'
# Create an instance of SQLAlchemy
db = SQLAlchemy(application)
and all you need is to make sure your models correspond to a database table like the model below
class Isps(db.Model):
__tablename__ = "isps"
isp_id = db.Column('isp_id', db.Integer, primary_key=True)
isp_name = db.Column('isp_name', db.String(80), unique=True)
isp_description = db.Column('isp_description', db.String(180))
# services = db.relationship('Services', backref="isps", cascade="all, delete-orphan",lazy='dynamic')
def __init__(self, isp_name, isp_description):
self.isp_name = isp_name
self.isp_description = isp_description
def __repr__(self):
return '<Isps %r>' % self.isp_name
and you can then learn the power of SQLAlchemy to do optimised queries
Flask-SQLAlchemy was written by Armin (the creator of Flask) to make it simple to work with SQLAlchemy. The pattern described in Flask's documentation is what you would use if you did not choose to use the Flask-SQLAlchemy extension.
As for MySQL vs. SQLite, the whole point of the SQLAlchemy ORM is to make it possible (for the most part) to ignore what database you are running against. SomeModel.filter(SomeModel.column == 'value') will work the same, regardless of what database you are connecting to.
Related
***import pandas as pd
employees = {'Name of Machining': ['milling','Drilling','Drilling','Chamfering'],
'Speed': [275,275,275,275],
'Feed': [0.28,0.03,0.03,0.28],
'Tool': ['EndMill','TwistDrill','TwistDrill','EndMill']
}
df = pd.DataFrame(employees, columns= ['Name of Machining','Speed','Feed','Tool'])***
i have used panda to contruct a table here. I am working on the project to save the table in
a database how can i save the table so constructed in a database)
print (df)
If it's a MySQL database, you can use the SQLAlchemy toolkit.
Make sure to run this in your terminal (for Windows) to install the packages :
pip install sqlalchemy pymysql
And then you can use pandas.DataFrame.to_sql to create, append or overwrite a table :
import pandas as pd
from sqlalchemy import create_engine
# - Creating the dataframe
employees = {'Name of Machining': ['milling','Drilling','Drilling','Chamfering'],
'Speed': [275,275,275,275],
'Feed': [0.28,0.03,0.03,0.28],
'Tool': ['EndMill','TwistDrill','TwistDrill','EndMill']
}
df = pd.DataFrame(employees)
# - Creating an engine to connect to MySQL Database
host, db, user, pw = "localhost", "mydb_name", "my_user_name", "my_password"
engine = create_engine(f"mysql+pymysql://{user}:{pw}#{host}/{db}")
# - Inseting the dataframe to the MySQL table
df.to_sql('employees', engine, index=False)
Read here in the official documentation to understand more.
I'm new to using pyathena and also SQLalchemy (or DBAPI in general). We are using pyathena to and SQLalchemy to query the data in our S3 bucket but we need to connect with our work_group rather than aws_access_id or secret key. The pyathena page in pypi gives the example below, but I need to be able to replace conn_str such that we don't use {aws_access_key_id} or {aws_secret_access_key} and use our Athena work group to connect and run queries. I've been searching online but it seems like a very rare issue, does anyone more familiar with Athena/AWS/pyathena/SQLAlchemy have any suggestions?
from urllib.parse import quote_plus
from sqlalchemy.engine import create_engine
from sqlalchemy.sql.expression import select
from sqlalchemy.sql.functions import func
from sqlalchemy.sql.schema import Table, MetaData
conn_str = "awsathena+rest://{aws_access_key_id}:{aws_secret_access_key}#athena.{region_name}.amazonaws.com:443/"\
"{schema_name}?s3_staging_dir={s3_staging_dir}"
engine = create_engine(conn_str.format(
aws_access_key_id=quote_plus("YOUR_ACCESS_KEY_ID"),
aws_secret_access_key=quote_plus("YOUR_SECRET_ACCESS_KEY"),
region_name="us-west-2",
schema_name="default",
s3_staging_dir=quote_plus("s3://YOUR_S3_BUCKET/path/to/")))
with engine.connect() as connection:
many_rows = Table("many_rows", MetaData(), autoload_with=connection)
result = connection.execute(select([func.count("*")], from_obj=many_rows))
print(result.scalar())
I am trying to connect to a mysql database,
works fine with Option 1:
from sqlalchemy import create_engine
engine = create_engine('mysql://root:root#localhost/lend', echo=True)
cnx = engine.connect()
x = cnx.execute("SELECT * FROM user")
but breaks down here:
from pandas.io import sql
xx = sql.read_frame("SELECT * FROM user", cnx)
cnx.close()
with
AttributeError: 'Connection' object has no attribute 'rollback'
You need to have a raw database connection, and not an instance of Connection. In order to get it call either engine.raw_connection() or engine.connect().connection:
from pandas.io import sql
#cnx = engine.connect().connection # option-1
cnx = engine.raw_connection() # option-2
xx = sql.read_frame("SELECT * FROM user", cnx)
cnx.close()
Use the MySQLdb module to create the connection. There is ongoing progress toward better SQL support, including sqlalchemy, but it's not ready yet.
If you are comfortable installing the development version of pandas, you might want to keep an eye on that linked issue and switch to using the development version of pandas as soon as it is merged. While pandas' SQL support is usable, there are some bugs around data types, missing values, etc., that are likely to come up if you use Pandas + SQL extensively.
This is an old question but still relevant apparently. So past 2018 the way to solve this is simply use the engine directly:
xx = sql.read_sql("SELECT * FROM user", engine)
(originally posted by Midnighter in a comment)
I'm using alembic migrations for a flask+sqlalchemy project and things work as expected till I try to query the models in alembic.
from models import StoredFile
def upgrade():
### commands auto generated by Alembic - please adjust! ###
op.add_column('stored_file', sa.Column('mimetype', sa.Unicode(length=32))
for sf in StoredFile.query.all():
sf.mimetype = guess_type(sf.title)
The above code gets stuck after adding column and never comes out. I guess the StoredFile.query is trying to use a different database connection than the one being used by alembic. (But why? Am I missing something in env.py?)
I could solve it by using the op.get_bind().execute(...) but the question is how can I use the models directly in alembic?
You should not use classes from models in your alembic migrations. If you need to use model classes, you should redefine them in each migration file to make the migration self-contained. The reason is that multiple migrations can be deployed in one command, and it's possible that between the time the migration was written and until it is actually performed in production, the model classes have been changed in accordance with a "later" migration.
For example, see this example from the documentation for Operations.execute:
from sqlalchemy.sql import table, column
from sqlalchemy import String
from alembic import op
account = table('account',
column('name', String)
)
op.execute(
account.update(). \
where(account.c.name==op.inline_literal('account 1')). \
values({'name':op.inline_literal('account 2')})
)
Tip: You don't need to include the full model class, only the parts that are necessary for the migration.
I had the same problem. When you use StoredFile.query you are using a different session than Alembic is using. It tries to query the database but the table is locked because you're altering it. So the upgrade just sits there and waits forever because you have two sessions waiting for each other. Based on #SowingSadness response, this worked for me:
from models import StoredFile
def upgrade():
### commands auto generated by Alembic - please adjust! ###
op.add_column('stored_file', sa.Column('mimetype', sa.Unicode(length=32))
connection = op.get_bind()
SessionMaker = sessionmaker(bind=connection.engine)
session = SessionMaker(bind=connection)
for sf in session.query(StoredFile):
sf.mimetype = guess_type(sf.title)
session.flush()
op.other_operations()
I love OOP and immediately I learned about SQLAlchemy is was very interested in. I am new in it though and having issues one not really an issue but somewhat annoying for a beginner is having to import each module explicitly even after importing the master module, I mean sqlalchemy.
I have this script to create a new database file and to alert me if a database of the same name already exist but I am getting it wrong unlike working straight on sqlite3.
import os
import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
def CreateDB(dbName=None):
dbName = 'ABC-DB' # should be the name of the new database file
db = create_engine('sqlite:///dbName', echo=False) # should be a link from above
Base.metadata.create_all(db)
if os.path.isfile(dbName): # should check for existence
print('DataBase already exist') # should alert on existence.
I get 'dbName' instead of 'ABC-DB'.
The os.path... is a dead script as it does nothing.
Someone please help.
Correct, it did exactly what you told it to:
db = create_engine('sqlite:///dbName', echo=False) # should be a link from above
You want:
db = create_engine('sqlite:///' + dbName, echo=False) # should be a link from above