Flask + SQLAlchemy + Sqlite объект не добавляется в базу
Я постараюсь очень кратко, код будет обрывочным, постараюсь не лить лишнее. Скажу лишь, что построчно все проверял в консоли, ошибки приложу ниже. Есть у меня класс с пятью полями, первое и пятое понятно.
class Article(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
intro = db.Column(db.String(300), nullable=False)
text = db.Column(db.Text, nullable=False)
date = db.Column(db.DateTime, default=datetime.utcnow)
def __repr__(self):
return '<Article %r>' % (self.id)
Форма заполнения объекта:
<form action="/create-article" method="post">
<input type="text" name="title" id="title" class="form-control"></br>
<textarea name="intro" id="intro" class="form-control"></textarea></br>
<textarea name="text" id="text" class="form-control"></textarea></br>
<input type="submit" class="btn btn-success" value="Отправить">
Затем при методе post просто создаю объект заполненными полями
def create_article():
if request.method == 'POST':
title = request.form['title']
intro = request.form['intro']
text = request.form['text']
article = Article(title=title, intro=intro, text=text)
with app.app_context():
try:
db.session.add(article)
db.session.commit()
return redirect('/')
except:
return 'Error'
else:
return render_template('create-article.html')
Сначала довольно долго не мог создать саму базу, как я понял, в новой версии Фласка такая проблема. Почитал документацию, приходится дописывать
with app.app_context():
иначе
This typically means that you attempted to use functionality that needed the current application. To solve this, set up an application context
with app.app_context()
. See the documentation for more information.
Ну и при добавлении статьи в базу тоже идет только так.
Возвращает 'Error'
Пробовал все построчно в консоли, на шаге db.session.commit()
ошибка
> sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: article
[SQL: INSERT INTO article (title, intro, text, date) VALUES (?, ?, ?, ?)]
[parameters: ('title', 'intro', 'text', '2024-03-13 04:25:38.283046')]
(Background on this error at: https://sqlalche.me/e/20/e3q8)
Но экземпляр класса создан, к нему можно обращаться. Прикладываю скриншот.
Конечно, базу я создал после того, как разобрался с app_context
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///blog.db'
И в консоли в три поля просто вручную добавил одноименные строки, для теста.
Якобы объекта article не существует. Очень прошу помочь разобраться.
Ответы (2 шт):
Предполагаю из-за того что
довольно долго не мог создать саму базу
база создалась, а таблица в базе не создалась.
Можно в каком-нибудь редакторе sqlite добавить таблицу.
Можно создать и выполнить одноразовый скрипт:
from sqlalchemy import create_engine,Table,MetaData, Column, String, Integer, Text, DateTime,select
from sqlalchemy.inspection import inspect
import datetime
# Создаем движок
engine=create_engine('sqlite:///mysqlite.db',echo=True)
metadata=MetaData()
# Описываем таблицу базы данных
article=Table('article', metadata,
Column('id',Integer, primary_key=True),
Column('title',String(100), nullable=False),
Column('intro',String(300), nullable=False),
Column('text',Text, nullable=False),
Column('date',DateTime, default=datetime.datetime.utcnow)
)
# Это если несколько раз запускать программу, проверка если таблица есть, то удалить и создать
inspector=inspect(engine)
if article.name in inspector.get_table_names():
article.drop(bind=engine)
article.create(bind=engine)
else:
article.create(bind=engine)
#Записать тестовые данные
data=[{ 'title':'Здесь заголовок',
'intro':'Коротко о главном',
'text':'Основной текст'
},
{ 'title':'Здесь другой заголовок',
'intro':'Коротко о главном вторая запись',
'text':'Основной текст полностью'
}
]
insdata=article.insert().values(data)
with engine.begin() as con:
con.execute(insdata)
#Вывести тестовые данные
with engine.begin() as con:
res=con.execute(select(article))
for el in res:
print(el)
(1, 'Здесь заголовок', 'Коротко о главном', 'Основной текст', datetime.datetime(2024, 3, 13, 7, 30, 46, 674496))
(2, 'Здесь другой заголовок', 'Коротко о главном вторая запись', 'Основной текст полностью', datetime.datetime(2024, 3, 13, 7, 30, 46, 674496))
Чтобы логи не выводились, исправить engine=create_engine('sqlite:///mysqlite.db',echo=False)
Проблема была из-за создания бд через сам .py файл. Чтобы избежать проблемы, в терминале поочередно введите команды
python
from app import app
from app import db
with app.app_context():
db.create_all()
После двоеточия не забудьте четыре пробела или еретический таб. Файл должен создаться в проекте, и его размер не должен быть нулевым (как было у меня). Также при любых операциях с бд, обязательно нужно использовать конструкцию
with app.app_context():
#операция с бд (добавление, удаление и тд)