【问题标题】:POST method to SQL using Stored Procedure call in Flask-SQL Alchemy在 Flask-SQLAlchemy 中使用存储过程调用 POST 方法到 SQL
【发布时间】:2019-12-07 06:50:09
【问题描述】:

我有一个有效的 SQL 存储过程,并在 Python 中设置了 flask-sqlAlchemy 并连接到我的 MySQL 数据库。我正在尝试构建一个简单的 API,它将接收通过 URL 请求输入的 6-7 个请求参数并将它们发送到我的调用过程,并根据在 DB 表中插入新记录的存储过程相应地更新数据库( sp 是下面的“add_spotting”)。

我正在尝试通过 POST 方法执行此操作,并相信我正确地接收了请求参数并调用了该过程,但我不确定如何执行这些过程并实际注入数据库。

class Spotting(mysql.Model):
    __tablename__ = 'spotting'
    spotting_id = mysql.Column(mysql.Integer, primary_key = True)
    animal_id = mysql.Column(mysql.Integer, mysql.ForeignKey('animal.animal_id'), nullable=False)
    user_id = mysql.Column(mysql.Integer, mysql.ForeignKey('user.user_id'), nullable=False)
    trail_id = mysql.Column(mysql.Integer, mysql.ForeignKey('trail.trail_id'), nullable=False)
    quantity = mysql.Column(mysql.Integer, nullable = False)
    lat = mysql.Column(mysql.Float, nullable=True)
    lon = mysql.Column(mysql.Float, nullable=True)
    description = mysql.Column(mysql.String(250), nullable=False)


#Post method 
@application.route('/spotting', methods=['POST'])
def postSpotting():
    animal = request.args.get('animal')
    user = request.args.get('user')
    trail = request.args.get('trail')
    quantity = request.args.get('quantity')
    lat = request.args.get('lat')
    lon = request.args.get('lon')
    desc = request.args.get('desc')
    proc_call = "call add_spotting('" + animal + "','"+ user + "','" + trail + \
                "','" + quantity + "','" + lat + "','" + lon + "','" + desc + "')"
    mysql.engine.execute(proc_call)

    ### Here I want to post and commit this to the MySQL DB via the stored proc and return a message such as
    # ## 'Spotting successfully added'
    return ("Successfully posted!")

【问题讨论】:

  • 嗨@Shane,你介意分享数据库模型的代码吗?
  • @calestini 当然!我在上面添加了它——我不确定我的数据模型是否完整,或者我是否真的需要它来用于这个 post 方法。我已经用数据填充并存储了我的数据库,因此我不需要通过 Python 创建它,但我确实希望能够使用 API 来演示通过我的存储过程进行的简单插入。

标签: python stored-procedures flask sqlalchemy flask-sqlalchemy


【解决方案1】:

如果您只想使用您提供的代码测试POST 请求,您可以简单地使用数据库模型对象来填充它:

#Post method 
@application.route('/spotting', methods=['POST'])
def postSpotting():
    animal = request.args.get('animal')
    user = request.args.get('user')
    trail = request.args.get('trail')
    quantity = request.args.get('quantity')
    lat = request.args.get('lat')
    lon = request.args.get('lon')
    desc = request.args.get('desc')
    proc_call = "call add_spotting('" + animal + "','"+ user + "','" + trail + \
                "','" + quantity + "','" + lat + "','" + lon + "','" + desc + "')"
    mysql.engine.execute(proc_call)

    ### create a new instance of your model
    new_post = Post()
    new_post.lat = lat
    new_post.lon = lon
    ... #etc

    ### commit your changes
    session = db.session
    session.add(new_post)
    db.session.commit()

    # ## 'Spotting successfully added'
    return ("Successfully posted!")

话虽如此,我要指出两点:

  1. 在通过 url 参数插入数据时应该小心。更推荐的方法是将data 传递给您的POST 请求,并可能通过表单或身份验证进行验证

  2. 你可以为你的模型类创建一个启动器,这样更容易插入数据。例如:

class Spotting(mysql.Model):
    __tablename__ = 'spotting'
    spotting_id = mysql.Column(mysql.Integer, primary_key = True)
    animal_id = mysql.Column(mysql.Integer, mysql.ForeignKey('animal.animal_id'), nullable=False)
    user_id = mysql.Column(mysql.Integer, mysql.ForeignKey('user.user_id'), nullable=False)
    trail_id = mysql.Column(mysql.Integer, mysql.ForeignKey('trail.trail_id'), nullable=False)
    quantity = mysql.Column(mysql.Integer, nullable = False)
    lat = mysql.Column(mysql.Float, nullable=True)
    lon = mysql.Column(mysql.Float, nullable=True)
    description = mysql.Column(mysql.String(250), nullable=False)

    def __init__(self, lat, lon): #etc
        self.lat = lat
        self.lon = lon
        ## etc

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

【讨论】:

  • 谢谢。创建模型对象并将其传递给数据库是有意义的。但是,我们想利用我们创建的 SQL 存储过程,它只接受 6 个参数(动物、用户、跟踪、数量、纬度、经度、降序),然后使用这些参数在SQL 数据库,因此插入的实际数据比请求输入的数据稍稍插入。例如,用户可以插入他们的用户名、动物名、轨迹名……但实际的数据库表有各自的 user_id、animal_id 等
  • 我看到@Shane,这是有道理的。关于如何使用 sqlalchemy here 调用存储过程有一个很好的线程,它可能更有见地
  • "call add_spotting('" + animal + "','"+ user + "','" + trail + \ "','" + quantity + "','" + lat + "','" + lon + "','" + desc + "')" 可以注射了。应该改用"call add_spotting(:animal, :user, :trail, :quantity, :lat, :lon, :desc)"mysql.engine.execute(text(proc_call), animal=animal, ...)
猜你喜欢
  • 2021-08-13
  • 2018-01-10
  • 1970-01-01
  • 1970-01-01
  • 2016-01-23
  • 2016-08-06
  • 2011-04-03
  • 2020-01-24
相关资源
最近更新 更多