Flask-SQLAlchemy ничего не делает - PullRequest
0 голосов
/ 17 октября 2018

Я учусь создавать API с использованием Python, Flask и SQLAlchemy.Когда я начал интегрировать SQLAlchemy в мой код, любой запрос, который пытался использовать SQLAchemy, просто ничего не делал.Коды ошибок нет, просто сидит и крутится.Вот основная часть моего кода:

App.py

from flask import Flask
from flask_restful import Api
from flask_jwt import JWT

from security import authenticate, identity
from Resources.user import UserRegister
from Resources.item import Item, ItemList


app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = "postgresql://postgres:mypassword@localhost:5000/mydatabase"
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['PROPAGATE_EXCEPTIONS'] = True
app.secret_key = 'jose'
api = Api(app)


jwt = JWT(app, authenticate, identity)

api.add_resource(Item, '/item/<string:name>')
api.add_resource(ItemList, '/items')
api.add_resource(UserRegister, '/register')

if __name__ == '__main__':
    from db import db
    db.init_app(app)
    app.run(port = 5000, debug = True)

db.py

from flask_sqlalchemy import SQLAlchemy 

db = SQLAlchemy()

item.py-Models

from db import db

class ItemModel(db.Model):
    __tablename__ = 'parts'

    partid  = db.Column(db.Integer, primary_key = True)
    partdescript = db.Column(db.String(80))
    lastcost = db.Column(db.Float(precision=2))


    def __init__(self, partid, partdescript, _price):
        self.partid = partid
        self.partdescript = partdescript
        self.price = price


    def json(self):
        return {'name': self.partid, 'partdescript': self.partdescript, 'price':self.price}

    @classmethod
    def find_by_name(cls, partid):
        print("find_by_name")
        #print(partid)
        #print(cls.query.filter_by(partid = partid))

        qry = cls.query.filter_by(partid = partid).first()  # this is where it is getting stuck

        return qry

    def save_to_db(self):

        db.session.add(self)
        db.session.commit()


    def delete_from_db(self):
        db.session.delete(self)
        db.session.commit()

item.py-Resources

from flask_restful import Resource, reqparse
from flask_jwt import jwt_required
from Models.item import ItemModel

class Item(Resource):
    parser = reqparse.RequestParser()

    parser.add_argument(
        'partdescript',
        type = str,
        required = False,
        help = "This field cannot be left blank!"
    )

    parser.add_argument(
        'lastcost',
        type = float,
        required = True,
        help = "This field cannot be left blank!"
    )

    #@jwt_required()
    def get(self, name):
        #print("get")
        part = ItemModel.find_by_name(name)
        #print(part)

        if part:
            #print("get if statement")
            return part.json(), 201
        return {'message': 'Part not found'}, 404

    @jwt_required()
    def post(self, name): #need to have the parser.add_argument for each field
        if ItemModel.find_by_name(name):
            return {'message': "An item with name '{}' already exists.".format(name)}, 400

        data = Item.parser.parse_args()

        item = ItemModel(name, data['partdescript'], data['lastcost'])

        try:
            item.save_to_db()
        except:
            return {"message": "An error occurred inserting the item."}, 500

        return item.json(), 201

    @jwt_required()
    def delete(self, name):
        item = ItemModel.find_by_name(name)
        if item:
            item.delete_from_db()

        return {'message': 'Item deleted'}

    @jwt_required()
    def put(self, name):
        data = Item.parser.parse_args()

        item = ItemModel.find_by_name(name)
        updated_item = ItemModel(name, "",data['lastcost']) #might need to put item descript in

        if item is None:
            item = ItemModel(name, data['lastcost'])
        else:
            item.lastcost = data['lastcost']

        item.save_to_db()

        return item.json()


class ItemList(Resource):
    @jwt_required()
    def get(self):
        return {'items': [item.json() for item in ItemModel.query.all()]}

Если я просто использую python для правильного доступа к своей базе данных, функция запросов отлично работает.Это только когда я пытаюсь использовать SQLAlchemy.Кто-то, кому я помогал, подумал, что это может быть из-за того, что у меня был SQLAlchemy и прямой доступ к моему коду.Я преобразовал все в SQLAlchemy, и теперь все запросы просто сидят и крутятся.Мой старый код, который не использует SQLAlchemy, все еще работает.

Вещи, которые я пробовал: Перезагрузка системы Удалите и переустановите SQLAlchemy, отправляя запросы с использованием cURL вместо Postman, вводя неправильное имя базы данных в соединение, чтобы увидеть, получу ли я ошибку.запуск всех приложений от имени администратора

Я вставил несколько операторов печати, чтобы найти причину сбоя.Если я удаляю .first () или .all (), тогда мой код продолжает выполняться, и я могу напечатать, каким должен быть запрос, но это также делает его таким, что запрос вообще не отправляется.

Любые идеи, почему SQLAchemy просто сидеть и вращаться?

1 Ответ

0 голосов
/ 17 октября 2018

Я не уверен, что это тот код, который есть, но ваш URI соединения с базой данных, похоже, указывает назад на ваше приложение фляги.

app.config['SQLALCHEMY_DATABASE_URI']="postgresql://postgres:mypassword@localhost:5000/mydatabase"

5000 - порт по умолчанию для приложений фляги.

5432 - это порт по умолчанию для postgres.

Первым моим предложением было бы убедиться в правильности URI подключения, который вы предоставляете SQLAlchemy.

SQLAlchemy непопытаться подключиться к базе данных при запуске приложения фляги;он будет пытаться подключиться к базе данных только при выполнении первого запроса.

Возможно, вы столкнулись с тупиковой ситуацией, когда ваше приложение пытается подключиться к базе данных через порт 5000, но через порт 5000 (ваше приложение фляги).) не отвечает, поскольку в данный момент он пытается установить соединение с базой данных.

См. этот ответ , который указывает, что только один запрос может быть обработан за один раз при использовании колбы.сервер с параметрами по умолчанию.

...