Что-то не так с моей моделью SQLAlchemy SQLite Flask Python

#python #sqlite #flask #sqlalchemy #flask-sqlalchemy

#python #sqlite #flask #sqlalchemy #flask-sqlalchemy

Вопрос:

Что-то не так с моей моделью? вы видите какую-либо аномалию? Пытаюсь сохранить пользователя и пароль в SQLite db с помощью SQLAlchemy, но возвращает ошибку, в которой говорится, что столбец pwd в таблице user не существует, действительно, если я проверяю sqlite> .schema, он возвращает таблицу с правильной структурой и столбцом pwd, но никаких данных внутри, если я запрашиваю.

Сначала я создаю таблицу с помощью функции Table(), затем в разделе я определяю класс User, может быть, потому, что в классе нет ссылок на имена столбцов таблицы? но я импортировал tablename=»user», поэтому он не должен работать?

 from flask import Flask 
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from sqlalchemy import *

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///data-users.sqlite'
db = SQLAlchemy(app)

class User(db.Model):
    
    id = db.Column(db.Integer(), primary_key = True, autoincrement=True)
    username = db.Column(db.String(64), unique = True)
    pwd = db.Column(db.String())

    def __repr__(self):
        return '<User %r>' % self.username
  

Здесь я сохраняю пользовательские данные в таблице

         from store_user_db import User, db

        db.create_all()

        DICP_FTP_DESTINATION_PSW=self.submit_pwd()

        user = User(id=001,username="ita_itf",pwd=DICP_FTP_DESTINATION_PSW)
        db.session.add(user)
        db.session.commit()
  

Это ошибка:

 sqlalchemy.exc.OperationalError

OperationalError: (sqlite3.OperationalError) table user has no column named pwd
[SQL: INSERT INTO user (id, username, pwd) VALUES (?, ?, ?)]
[parameters: (1, 'ita_itf', <read-only buffer for 0x7efe495709f0, size -1, offset 0 at 0x7efe500c3830>)]
  

Комментарии:

1. может быть, вместо ссылки на db я должен ссылаться на имя таблицы? нравится userstable. Столбец (…) вместо db.Column(…)??

Ответ №1:

db.create_all() Будет создавать таблицы только в том случае, если они еще не существуют. Я подозреваю, что ваша проблема заключается в том, что вы создали таблицу в недавнем прошлом, в тот момент, когда у вас еще не было pwd столбца в вашей модели.

Итак, теперь вы запускаете, db.create_all() и это по существу ничего не делает (поскольку user таблица уже существует), но падает, когда вы пытаетесь получить доступ к никогда не созданному pwd столбцу.

Вы можете db.drop_all() уничтожить все текущие таблицы или вручную (или с помощью инструмента миграции) добавить столбец ‘missing’ pwd , чтобы база данных соответствовала модели.

Кроме того, весь этот код ничего не делает в этом конкретном примере (если вы не делаете что-то необычное в коде, который вы не включили).

 engine= create_engine(app.config['SQLALCHEMY_DATABASE_URI'])

#CREATE TABLE
meta=MetaData()
userstable = Table('user', meta, 
    Column('id', Integer, primary_key = True, autoincrement=True), 
    Column('username', String, unique = True), 
    Column('pwd', LargeBinary,unique = True))
meta.create_all(engine)
  

Пример рабочей версии

 from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt

app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///example.sqlite3"

bcrypt = Bcrypt(app)
db = SQLAlchemy(app)


class User(db.Model):
    __tablename__ = "user"
    id = db.Column(db.Integer(), primary_key=True, autoincrement=True)
    username = db.Column(db.String(64), unique=True)
    pwd = db.Column(db.LargeBinary(), unique=True)

    def __init__(self, id, username, pwd):
        self.id = id
        self.username = username
        self.pwd = bcrypt.generate_password_hash(pwd)


if __name__ == "__main__":
    db.drop_all()  # destroy all the tables.
    db.create_all()  # create all fresh new tables.
    u = User(1, "static", "password")
    db.session.add(u)
    db.session.commit()

    u = User.query.first()  # check out data got stored.
    print(u.pwd)
  

Комментарии:

1. Я понял вашу точку зрения, и я удалил db.create_all(), я удалил пользователя таблицы в sqlite, дважды проверил и там нет таблицы. затем я снова запускаю свое приложение, и оно создает правильную таблицу со столбцом pwd, я проверяю это в sqlite>.schema, и pwd там есть, но все равно возвращает следующую ошибку

2. OperationalError: (sqlite3. OperationalError) у пользователя таблицы нет столбца с именем pwd

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

4. возможно, когда я пытаюсь сохранить пароль, я использую db.session.add (user), но когда я создаю таблицу, действительно нет ссылки на db. Может быть, это? не предполагается ли ссылка на таблицу?

5. Если вы измените app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///data-users2.sqlite' на app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///data-users2.sqlite3' , сохраняется ли та же проблема? (Интересно, удаляете ли вы неправильную таблицу SQLLite)