sqlalchemy.exc.OperationalError: (MySQLdb._exceptions.OperationalError) (1054, «Неизвестный столбец« detail.id »в« списке полей »») - PullRequest
0 голосов
/ 25 сентября 2019

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

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

sqlalchemy.exc.OperationalError: (MySQLdb._exceptions.OperationalError) (1054, «Неизвестный столбец detail.id» в «списке полей» ») [SQL: SELECT detail.id AS detail_id, detail.name AS detail_name, detail.email AS detail_email, detail.phone AS detail_phone, detail.date AS detail_date FROM detail] (Справочная информация об этой ошибке: http://sqlalche.me/e/e3q8)

Мой код run.py:

from flask import Flask, render_template, request, redirect, url_for, session
from db import db
import datetime

# Every website is application in 'flask'
app = Flask(__name__, template_folder='template')
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:''@localhost/flask' # 'test' is name of your database
# Database access through 'username'= root  and 'password'= None
# My username is 'root' cause I'm on the local host and I'd set any password
# One more thing password is after two dots :
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True



# database access
class detail(db.Model):
    def __init__(self, name, phone, email):
        self.name = name
        self.email = email
        self.phone = phone

    # table name as is it in your database
    __tablename__='detail'
    # give column names same as in your database otherwise it will give you error
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(20), nullable=False)
    email = db.Column(db.String(20), nullable=False)
    phone = db.Column(db.String(13), nullable=False)
    date=db.Column(db.DateTime, default=datetime.datetime.strftime(datetime.datetime.now(), '%d-%m-%Y   %I:%M:%S'))



# routing( setting end points in website) with ['post', 'get'] method
@app.route('/', methods=['POST', 'GET'])
def index():
    if request.method=='POST':
        name = request.form['name']
        email = request.form['email']
        phone = request.form['phone']

        try:
            # commit to add value in database
            data = detail(name=name, email=email, phone=phone)
            db.session.add(data)
            db.session.commit()

            # after commit redirect to this page
            return redirect(url_for('index'))

        except Exception as e:
            return e

    else:
        # retrieve data from database
        # here is problem
        data =  detail.query.all()  #<<<------------------------------- Error
        return render_template('index.html', data=data)




if __name__ == '__main__':
    # here we are telling to 'flask' that integrate db in 'app'
    db.init_app(app)
    # run flask app and you might be thinking debug mean that if you'll do any change in your application so it'll restart server auto
    app.run(debug=True)

Мой db.py файл:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

'''here we are init. 'username ' and 'password' because if you'll config
this in your 'main.py application' so it'll not be work
so you have to keep it in a another file and import from there
'''
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:''@localhost/flask'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True

db = SQLAlchemy(app)

Мой index.html файл:

<!--
This is just a simple website it will add your 'name' and 'address', 'phone' in database
-->
<html>

<head>
  <title> First flaks app</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <!-- Latest compiled and minified CSS -->
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">

  <!-- jQuery library -->
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

  <!-- Popper JS -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>

  <!-- Latest compiled JavaScript -->
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>

  <script src="https://kit.fontawesome.com/f6cee5f9d4.js" crossorigin="anonymous"></script>
</head>

<body>
  <h1 class="text-warning text-center">Flask-app-connect to database</h1>
  <div class='container table-responsive w-50 mt-5'>
    <table class="table table-dark table-hover">
      <thead class='bg-info text-dark'>
        <tr>
          <th>Name</th>
          <th>Email</th>
          <th>Phone</th>
        </tr>
      </thead>
      {% for data in data %}
        <tbody>
          <tr>
            <td>{{data.Name}}</td>
            <td>{{data.Email}}</td>
            <td>{{data.Phone}}</td>
          </tr>
        </tbody>
      {% endfor %}
    </table>
  </div>

  <div class="container text-center mt-5">
    <!-- Trigger the modal with a button -->
    <button type="button" class="btn btn-info btn-sm" data-toggle="modal" data-target="#myModal">Add to
      database</button>

    <!-- Box Modal -->
    <div class="modal fade" id="myModal" role="dialog">
      <div class="modal-dialog">

        <!-- Modal content-->
        <div class="modal-content">
          <div class="modal-header">
            <h2>Add to database</h2>

          </div>
          <div class="modal-body">
            <!-- Form -->
            <form action="/" method="POST" role="form" class="was-validated">
              <div class="form-group">
                <input type="text" class="form-control" placeholder="Name" name="name" required>
                <div class="valid-feedback">Valid.</div>
              </div>
              <div class="form-group">
                <input type="email" class="form-control" placeholder="Email" name="email" required>
                <div class="valid-feedback">Valid.</div>
              </div>
              <div class="form-group">
                <input class="form-control" type="phone" placeholder="Phone" name="phone" required>
                <div class="valid-feedback">Valid.</div>
              </div>
              <button type="submit" class="btn btn-warning btn-spinner">Commit</button>
            </form>
            <!-- Form end -->
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
          </div>
        </div>

      </div>
    </div>
    <!--End box modal-->

  </div>

</body>

</html>

Я ожидаю, что:

Как я могу получить все данные из базы данных и поместить их в index.html через цикл.

Пожалуйста, дайте мне понять, где я делаю ошибку?

1 Ответ

0 голосов
/ 25 сентября 2019

Понимание ошибки

Причина, по которой вы видите эту ошибку, заключается в том, что, как упомянул @moi, ваша модель и база данных не совпадают.

Ваша модель имеет пять атрибутов id, name, email, phone и date.Однако в вашей базе данных нет столбца с именем id в таблице detail.

Это вызывает ошибку при запросе к базе данных, поскольку SQLAlchemy указывает каждый столбец, к которому она обращается, в операторе SELECT.Другими словами, он говорит, что хочет получить данные из столбцов id, name, email, phone и date.К сожалению, в базе данных нет столбца с именем id, поэтому она возвращает ошибку.

Вероятно, это вызвано тем, что вы создали модель без id, а затем добавили ее позже.Таким образом, вы обновили свою модель, а не базу данных.

Как это исправить

Вам необходимо синхронизировать базу данных с вашей моделью.Вам нужно будет выполнить следующие команды с вашего терминала.

Во-первых, установите flask-migrate.

$ pip install Flask-Migrate

Во-вторых, настройте flask-migrate

Прочитайте раздел Пример в документации как минимум для этого. Flask Migrate Docs

В-третьих, настройте папку миграции.

$ flask db init

Если это приводит к ошибке Could not locate a Flask application..Вам нужно будет установить переменную окружения FLASK_APP.Замените run.py именем вашего приложения Flask.

MacOS / Linux

$ export FLASK_APP=run.py

Windows

$ set FLASK_APP=run.py

В-четвертых, создайте свою первую миграцию.

$ flask db migrate

Как только это будет сделано, вы должны найти новый файл xxxxxxxxxxxx_.py в вашем каталоге /migrations/versions.Это файл миграции Alembic.

На данный момент у вас есть три варианта.

Опция 1 : вы можете удалить свою таблицу details и позволить flask-migrateсоздать свежий. Вы потеряете все данные в нем. Затем выполните команду upgrade.

Опция 2 : вы можете вручную отредактировать новый файл миграции Alembic.Вам нужно будет изменить функцию upgrade(), чтобы она не пыталась создать новую таблицу details, поскольку она уже существует, а вместо этого добавляет столбец id.

Опция 3 : вы можете удалить строку sa.Column("id" sa.Integer()... из функции upgrade(), а также любые другие столбцы, отсутствующие в вашей базе данных.Затем вручную создайте таблицу в вашей базе данных с именем alembic_version с одним первичным ключом VARCHAR столбец с именем version_num длиной 32. Затем создайте одну запись в таблице alembic_version со значением Revision ID измиграция алемба, созданная выше.Затем снова запустите $ flask db migrate.Это создаст второй файл версии alembic, который сможет обновить вашу базу данных.

В зависимости от состояния вашего приложения и вашего уровня опыта я бы порекомендовал вариант 1.

В-пятых, обновите вашу базу данных.

$ flask db upgrade

Прочитайте документацию

Я настоятельно рекомендую прочитать документацию как по flask-migrate, так и по Alembic.Flask-migrate - это надежная оболочка для Alembic для аппликаций в колбах.

Документы для переноса колб

Документы Alembic

...