No such table error in Flask Python while attempting PUT method - python

Below is an example of what I'm trying to achieve but I keep getting an error. sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: object
basically i'm trying to PUT a data that has oid, and size. and then being able to GET it.
from flask import Flask, request
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite'
db = SQLAlchemy(app)
class Object(db.Model):
oid = db.Column(db.Integer, primary_key=True)
size = db.Column(db.Integer)
def __repr__(self):
return '<Object %r, Size: %r>' % self.oid % self.size
#app.route('/')
def index():
return 'DSAP_2022'
#app.route('/data/<repository>/<oid>', methods=['GET'])
def getObject(repository, oid):
obj = Object.query.filter_by(oid=oid).first()
if obj is None:
return 'Object not found', 404
return 'Object %r, Size: %r' % obj.oid % obj.size
#app.route('/data/<repository>', methods=['PUT'])
def putObject():
obj = Object(oid=request.json['oid'], size=request.json['size'])
db.session.add(obj)
db.session.commit()
return 'OK'
if __name__ == '__main__':
app.run(debug=True)
what am I doing wrong here?

Related

Cannot POST a JSON object to Database using Flask Python

I'm trying to post and get objects using Flask but I keep getting sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: object.
I tried doing POST into http://127.0.0.1/data
and the json I provided is
{
"oid": "123456789",
"size": "1234"
}
Below is my code
from flask import Flask, request
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite3'
db = SQLAlchemy(app)
class Object(db.Model):
oid = db.Column(db.Integer, primary_key=True)
size = db.Column(db.Integer)
def __repr__(self):
return f'Object: {self.oid}, Size: {self.size}'
#app.route('/')
def index():
return 'DSAP_2022'
#app.route('/data/<oid>', methods=['GET'])
def getObject(oid):
obj = Object.query.filter_by(oid=oid).first()
if obj is None:
return 'Object not found', 404
return repr(obj)
#app.route('/data', methods=['POST'])
def putObject():
obj = Object(oid=request.json['oid'], size=request.json['size'])
db.session.add(obj)
db.session.commit()
return 'OK'
if __name__ == '__main__':
app.run()
I am using Postman to submit my requests. and the index() works, however, both getObject and putObject doest not work because of the same error.
You're never calling db.create_all() to create the database tables. You would need something like:
from flask import Flask, request
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite3'
db = SQLAlchemy(app)
class Object(db.Model):
oid = db.Column(db.Integer, primary_key=True)
size = db.Column(db.Integer)
def __repr__(self):
return f'Object: {self.oid}, Size: {self.size}'
# Create tables corresponding to sqlalchemy models
db.create_all()
#app.route('/')
def index():
return 'DSAP_2022'
#app.route('/data/<oid>', methods=['GET'])
def getObject(oid):
obj = Object.query.filter_by(oid=oid).first()
if obj is None:
return 'Object not found', 404
return repr(obj)
#app.route('/data', methods=['POST'])
def putObject():
obj = Object(oid=request.json['oid'], size=request.json['size'])
db.session.add(obj)
db.session.commit()
return 'OK'
if __name__ == '__main__':
app.run()

Flask-testing : self.client.delete() return 200 but fail as he doesnt delete anything

I have a CRUD football player flask app using SQL Alchemy and postgresql.
I'm trying to test it with unittest and flask-testing but when I test delete and patch request on a player (based on his number), the statut returned is 200 but the player isn't deleted from the database so the test fail.
My app.py :
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI']='postgresql://postgres:password#localhost:5432/flask-sql-alchemy'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
modus = Modus(app)
class om_player(db.Model):
__tablename__ = "players"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Text)
number = db.Column(db.Integer)
age = db.Column(db.Integer)
def __init__(self, name, number, age):
self.name = name
self.number = number
self.age = age
#app.route('/joueurs/<int:number>', methods=["GET", "PATCH", "DELETE"])
def show(number):
found_player = om_player.query.filter_by(number=number).first()
if request.method == b"PATCH":
found_player.name = request.form['name']
found_player.number = request.form['number']
found_player.age = request.form['age']
db.session.add(found_player)
db.session.commit()
return redirect(url_for('show', number=request.form['number']))
if request.method == b"DELETE":
db.session.delete(found_player)
db.session.commit()
return redirect(url_for('joueurs'))
return render_template('show.html', player=found_player)
My test.py:
from app import app,db, om_player
from flask_testing import TestCase
import unittest
class BaseTestCase(TestCase):
def create_app(self):
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:password#localhost:5432/flask-sql-alchemy'
app.config['PRESERVE_CONTEXT_ON_EXCEPTION'] = False
return app
def test_delete(self):
response = self.client.delete('/joueurs/18', follow_redirects=True)
self.assertEqual(response.status_code, 200)
self.assertNotIn(b"AMAVI", response.data)
if __name__ == '__main__':
unittest.main()
(joueurs means players in french)
When I run python test.py :
AssertionError: b'AMAVI' unexpectedly found in b'my edit.html file'
So the player with number 18 and named "AMAVI" is not deleted and I don't understand why since the delete request return 200 and my app is working fine in local server.
If you're using Python3, b"PATCH" and b"DELETE" are no longer doing what you expect. Those tests are failing for "POST" and falling through to the default "GET" case.
Evaluate
"POST" == b"POST"
in a Python3 REPL for confirmation.

How can I pass to graphql more than one record using Orientdb and Flask?

I has the following code, i try to build and microservice that allow me get specific fields in my application, am beginning with orientdb and graphql:
from flask import Flask, request
import graphene
import json
import pyorient
app = Flask(__name__)
class Person(graphene.ObjectType):
name = graphene.String()
middle_name = graphene.String()
last_name = graphene.String()
class Query(graphene.ObjectType):
person = graphene.Field(Person, id=graphene.Argument(graphene.Int))
persons = graphene.Field(Person)
def resolve_person(self, info, id):
with open('orientdb_config.json') as config_file:
orient_config = json.load(config_file)
try:
client = pyorient.OrientDB(orient_config["host"], orient_config["port"])
session_id = client.connect(orient_config["user"], orient_config["password"])
client.db_open(orient_config["database"], orient_config["user"], orient_config["password"])
if client is not None:
query = "SELECT * FROM Person WHERE #rid = #12: %(id)s" % {'id': id}
data = client.query(query)
print(data[0])
return data[0]
else:
return None
except Exception as e:
return None
def resolve_persons(self, info):
with open('orientdb_config.json') as config_file:
orient_config = json.load(config_file)
try:
client = pyorient.OrientDB(orient_config["host"], orient_config["port"])
session_id = client.connect(orient_config["user"], orient_config["password"])
client.db_open(orient_config["database"], orient_config["user"], orient_config["password"])
if client is not None:
query = "SELECT * FROM Person"
data = client.query(query)
result = []
for d in data:
result.append(d)
return result
else:
return None
except Exception as e:
return None
schema = graphene.Schema(query=Query)
#app.route("/", methods=['POST'])
def main():
data = json.loads(request.data)
return json.dumps(schema.execute(data['query']).data)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5002, debug=True)
Everything seems to work when I request a Person using its id, but when I try to obtain all the people, graphql responds with a null value, I verify the result of the query and the value is there.
In your GraphQL definition, you should have
persons = graphene.List(lambda: Person)

FLASK RESTful API using GET to get a specific id and returning 201 using Python

I'm trying to get a todo_ID using GET method. I'm still new at using sqlalchemy and most of the things i have tried are telling me that sqlalchemy doesn't use them. Also, can someone tell me how to use HEAD, i want my methods to return http statuses, i kinda tried using them and imported the render template but when i try to use them it says it has no idea what they are.
this is my attempt at looking at a tutorial and making changes
from flask import Flask, jsonify,json, request, render_template, abort
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config.from_pyfile('Config.py')
db = SQLAlchemy(app)
class JsonModel(object): # Class for making objects JSON serializable
def as_dict(self):
return {c.name: getattr(self, c.name) for c in self.__table__.columns}
class User(db.Model, JsonModel): # Class which is a model for the User table in the database
User_ID = db.Column(db.Integer, primary_key = True)
FirstName = db.Column(db.String(20))
LastName = db.Column(db.String(20))
def __init__(self,User_ID,FirstName, LastName):
self.User_ID = User_ID
self.FirstName = FirstName
self.LastName = LastName
class Todo(db.Model, JsonModel): # Class which is a model for the Todo table in the database
todo_ID = db.Column(db.Integer, primary_key = True)
UserID = db.Column(db.Integer, db.ForeignKey("user.User_ID"))
details = db.Column(db.String(30))
def __init__(self, UserID, details):
self.UserID = UserID
self.details = details
#app.route('/todo', methods = ['GET']) # Uses GET method to return all information in the database.
def index():
return json.dumps([u.as_dict() for u in User.query.all()+Todo.query.all()]), 201
#app.route('/todo/<int:todo_ID>', methods = ['GET'])
def get(todo_ID):
query = Todo.query.get()
return {'todo': [dict(zip(tuple(query.keys()), i)) for i in query.cursor if i[1] == todo_ID]}
#app.before_first_request #Creates everything before the first request.
def startup():
db.create_all()
if __name__ == '__main__':
app.run()
My most recent attempt was:
#app.route('/todo/<int:todo_ID>', methods = ['GET'])
def get(todo_ID):
query = Todo.query("select * from Todo")
return {'todo': [dict(zip(tuple(query.keys()), i)) for i in query.cursor if i[1] == todo_ID]}
And the error that I get is this.
query = Todo.query("select * from Todo")
TypeError: 'BaseQuery' object is not callable
127.0.0.1 - - [30/Nov/2016 21:15:28] "GET /todo/1 HTTP/1.1" 500 -
If you want to query Todo by primary key and only return one record you can use:
from flask import jsonify
#app.route('/todo/<int:todo_ID>', methods = ['GET'])
def get(todo_ID):
response = {}
todo = Todo.query.get(todo_ID)
response['id'] = todo.id
response['user_id'] = todo.UserID
response['details'] = todo.details
response['status_code'] = 201
return jsonify(response)
Or you can use Marshmallow to have a serializer for each of your models so it can serialize them for you automatically.
Not sure I understand your problem, if your intention is to return json output as response and you want to control the status code, you could
use jsonify
from flask import jsonify
#app.route('/todo/<int:todo_ID>', methods = ['GET'])
def get(todo_ID):
query = Todo.query("select * from Todo")
response = {'todo': [dict(zip(tuple(query.keys()), i)) for i in query.cursor if i[1] == todo_ID]}
response = jsonify(response)
response.status_code = 201
return response

OperationalError: (sqlite3.OperationalError) no such table: user

I'm completely new to flask and web development in general. And what I need is to login to a website using steam id. I'm doing it as it said here, but get the following error:
OperationalError: (sqlite3.OperationalError) no such table: user
It seems to open up steam website correctly but it breaks when I press Log In. So, what's my mistake ? Any help is appreciated.
The code:
from flask import Flask, render_template, redirect, session, json, g
from flask_bootstrap import Bootstrap
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.openid import OpenID
import urllib
import re
app = Flask(__name__)
app.secret_key = '123'
Bootstrap(app)
app.config.from_pyfile('settings.cfg')
db = SQLAlchemy(app)
oid = OpenID(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
steam_id = db.Column(db.String(40))
nickname = db.String(80)
#staticmethod
def get_or_create(steam_id):
rv = User.query.filter_by(steam_id=steam_id).first()
if rv is None:
rv = User()
rv.steam_id = steam_id
db.session.add(rv)
return rv
def get_steam_userinfo(steam_id):
options = {
'key': app.config['STEAM_API_KEY'],
'steamids': steam_id
}
url = 'http://api.steampowered.com/ISteamUser/' \
'GetPlayerSummaries/v0001/?%s' % urllib.urlencode(options)
rv = json.load(urllib.urlopen(url))
return rv['response']['players']['player'][0] or {}
_steam_id_re = re.compile('steamcommunity.com/openid/id/(.*?)$')
#app.route('/login')
#oid.loginhandler
def login():
if g.user is not None:
return redirect(oid.get_next_url())
return oid.try_login('http://steamcommunity.com/openid')
#oid.after_login
def create_or_login(resp):
match = _steam_id_re.search(resp.identity_url)
g.user = User.get_or_create(match.group(1))
steamdata = get_steam_userinfo(g.user.steam_id)
g.user.nickname = steamdata['personaname']
db.session.commit()
session['user_id'] = g.user.id
flash('You are logged in as %s' % g.user.nickname)
return redirect(oid.get_next_url())
#app.before_request
def before_request():
g.user = None
if 'user_id' in session:
g.user = User.query.get(session['user_id'])
#app.route('/')
def homepage():
return render_template('mainpage.html')
#app.route('/logout')
def logout():
session.pop('user_id', None)
return redirect(oid.get_next_url())
if __name__ == '__main__':
app.run(debug=True)
You need to run a db.create_all() before running your app.
This will create all the tables described by your model in the database.
If you are new to flask you can follow the quickstart quide here

Categories

Resources