【问题标题】:Flask and sqlite: Failing to insert values into the databaseFlask 和 sqlite:无法将值插入数据库
【发布时间】:2020-10-16 12:04:21
【问题描述】:

我在 main.py 文件中有以下代码。它似乎在所有情况下都有效,请注意,当我打印出 user_details 时,它会打印出元组:test、test、test(填写表格),因此发布请求正在工作。但是,不知何故,它实际上并未写入数据库

错误的主要性质:插入没有发生。

有人能在我的代码中发现错误吗?

#ADD COMMENT GET POST REQUEST FUNCTION
@app.route('/add',methods=['GET','POST'])
def addcomment():
    if request.method=="GET":
        return render_template('addcomment.html')
    else:
        user_details=(
        request.form['title'],
        request.form['name'],
        request.form['comment']
            )
        #print(user_details)
        insertcomment(user_details)
        return render_template('addsuccess.html')

#INSERTING comments into the actual database
def insertcomment(user_details):
        connie = sqlite3.connect(db_locale)
        c=connie.cursor()
        sql_insert_string='INSERT INTO comments (title, name, comment) VALUES (?,?,?)';
        c.execute(sql_insert_string,user_details)
        connie.commit
        connie.close()
        print(user_details)


def query_comments():
        connie = sqlite3.connect(db_locale)
        c=connie.cursor()
        c.execute("""
        SELECT * FROM comments  

        """)
        userdata=c.fetchall()
        return userdata

我怀疑这些行有问题(即第二个功能) 插入评论()

    connie = sqlite3.connect(db_locale)
    c=connie.cursor()
    sql_insert_string='INSERT INTO comments (title, name, comment) VALUES (?,?,?)';
    c.execute(sql_insert_string,user_details)

据我所见,def addcomment(): 函数工作正常,在单击提交时呈现并返回正确的 html 页面。

在 html 方面,我能想到的唯一可能导致错误的是字段的顺序。在数据库中,字段是名称、标题、评论(按此顺序),但在 HTML 和查询中,它们是标题、名称、评论(按指定顺序)。

作为参考,HTML 文件(接受该数据的表单)如下:

  <div class="form-group">
    <label for="exampleInputEmail1">Title (or catchy caption!)</label>
    <input type="text" class="form-control" id="title" name="title" aria-describedby="emailHelp">
  </div>


  <div class="form-group">
    <label for="exampleInputPassword1">Name</label>
    <input type="text" class="form-control" id="name" name="name">
  </div>
  

  <div class="form-group">
  <label for="exampleFormControlTextarea1">Add your amazing answer here:</label>
  <textarea class="form-control" id="comment" name="comment" rows="3"></textarea>
  </div>


  </div>
  <div class="form-group">

  <button type="submit" class="btn btn-primary">Submit</button>
</form>

在首页,数据呈现如下。如您所见,我不得不切换数字,如 2=title 1=name 和 3=comment

{% for user in user_data%}
    <tr>
      <th scope="row">{{user[0]}}</th>
      <td>{{user[2]}}</td>
      <td>{{user[1]}}</td>
      <td>{{user[3]}}</td>
    </tr>
    {% endfor %}

以上是否与错误有关,我不知道(顺序)......但我想不出为什么。

最后,这里是表格填充 .py 文件。您会注意到有一个额外的字段 - 日期。同样,这可能是一个因素吗?

#populate database file
import sqlite3
db_locale='users.db'

connie=sqlite3.connect(db_locale)
c=connie.cursor() #use this to create commands

#creating a multi-line instruction
c.execute("""
INSERT INTO comments (name,title,comment,date_posted) VALUES
('Ruth Marvin','42','Yeah.Someone was going to say 42','20th July 2050'),
('Jonathan Peter','Meaning?','Surely we need to first define meaning','13th August 2050')

    """)

connie.commit()
connie.close()

谁能解释为什么数据没有被发布/插入到数据库中。

【问题讨论】:

    标签: database sqlite flask insertion


    【解决方案1】:

    错误在函数insertcomment() 中。您缺少commit 的括号:

    connie.commit
    

    只需更改为:

    connie.commit()
    

    这会将更改保存到数据库中。其他一切看起来都很好,包括数据库查询。使用参数化查询是正确的。

    【讨论】:

      【解决方案2】:
      sql_insert_string="INSERT INTO comments (title, name, comment) VALUES (%s,%s,%s)"
      c.execute(sql_insert_string, user_details)
      connie.commit()
      

      这应该可以。将您的 db 操作包装到 try 中,除了块以找出您的查询有什么问题。

      try:
        sql_insert_string="INSERT INTO comments (title, name, comment) VALUES (%s,%s,%s)"
        c.execute(sql_insert_string, user_details)
        connie.commit()
      except Exception as e:
        print(e)
      

      【讨论】:

        【解决方案3】:

        您需要使用标准库中 Python 的 format() 函数来格式化您的 SQL 插入字符串。

        您的代码:

        sql_insert_string='INSERT INTO comments (title, name, comment) VALUES (?,?,?)';
        

        应该是这样的:

        sql_insert_string='INSERT INTO comments (title, name, comment) VALUES ({}, {}, {})'.format(user_details[0], user_details[1], user_details[2])
        

        然后在您的 c.execute 行中,只需将 sql_insert_string 作为参数传递。另外,我发现flask-sqlalchemy 模块可以省去无数麻烦,但感谢您花时间学习 SQL 并像这样编写代码。

        【讨论】:

        • 字符串格式使您容易受到 sql 注入的攻击。请使用占位符 %s 并将参数(user_details[0]、user_details[1]、user_details[2])单独发送到执行函数,否则可能会使用 user_details 创建恶意 sql 查询。
        • 感谢您指出这一点...今天学到了一些新东西!
        • sql 注入是最常见的 Web 应用安全漏洞。它需要尽快根除。它仍然很常见,令人恐惧。
        猜你喜欢
        • 1970-01-01
        • 2021-03-11
        • 1970-01-01
        • 2013-06-18
        • 1970-01-01
        • 1970-01-01
        • 2011-02-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多