AIと生きる~Cursorでアプリ開発 #6~
開発の続き
OpenAIのAPIに課金した$10をほぼ使い果たした(残高$0.26)ので、少し手間ですが、「リートンのGPT-4Turbo」や、「Microsoft Copilot」の無料生成AIで開発を進めていきます。APIの残高は、ここぞというときに「GPT-3.5」で活用していきます。
データベースに保存されない原因を探る
メンテナンス管理ページの新規登録機能を実装進めています。最後のデータベースへの保存のところで、フォームで取得した値と、テーブルのカラムに保存する値の型が合わないようで、保存されないという現象に悩まされています。
そのときのコードが下記の部分です。
@app.route('/register_maintenance', methods=['POST'])
def register_maintenance():
maintenance_form = MaintenanceForm()
employees = Employee.query.all()
maintenance_form.recipient_id.choices = [(employee.id, employee.name) for employee in employees]
maintenance_form.maintenance_person_id.choices = [(employee.id, employee.name) for employee in employees]
if maintenance_form.validate_on_submit():
recipient_id = request.form['recipient_id']
maintenance_person_id=request.form['maintenance_person_id']
maintenance = Maintenance(
customer_id=maintenance_form.customer_id,
date_of_receipt=maintenance_form.date_of_receipt,
recipient_id = recipient_id,
model_number=maintenance_form.model_number,
maintenance_person_id=maintenance_person_id,
paid_free=maintenance_form.paid_free,
number_of_days_deposited=maintenance_form.number_of_days_deposited,
scheduled_return_date=maintenance_form.scheduled_return_date,
return_processing_date=maintenance_form.return_processing_date,
returned_unreturned=maintenance_form.returned_unreturned
)
db.session.add(maintenance)
db.session.commit()
return redirect(url_for('index'))
return render_template('maintenance_management.html', maintenance_form=maintenance_form, employees=employees)
if文の箇所で、ページから値を受け取って、データベースに保存するコードを書いています。これが成功すると、indexページが表示されるようになっていますが、ページで送信ボタンを押すと、メンテナンス管理ページのTOPに戻ってしまいます。つまり、データベースへの保存ができていないということです。
ただ、コードとしては成立しているので、Cursorでエラーが出ません。
これだとユーザーも何が起こったのか理解できないので、エラーメッセージを表示するように、最後の行を変更しました。
#変更前
return render_template('maintenance_management.html', maintenance_form=maintenance_form, employees=employees)
#変更後
return f'登録できませんでした。最初からやり直してください。'
このコードをコピーして、リートンに貼り付け、「下記のコードにエラーログが出力されるようにして」とプロンプト(質問)を入力しました。
返ってきたコードが下記です。
@app.route('/register_maintenance', methods=['POST'])
def register_maintenance():
maintenance_form = MaintenanceForm()
try:
employees = Employee.query.all()
maintenance_form.recipient_id.choices = [(employee.id, employee.name) for employee in employees]
maintenance_form.maintenance_person_id.choices = [(employee.id, employee.name) for employee in employees]
if maintenance_form.validate_on_submit():
recipient_id = request.form['recipient_id']
maintenance_person_id = request.form['maintenance_person_id']
maintenance = Maintenance(
customer_id=maintenance_form.customer_id.data,
date_of_receipt=maintenance_form.date_of_receipt.data,
recipient_id=recipient_id,
model_number=maintenance_form.model_number.data,
maintenance_person_id=maintenance_person_id,
paid_free=maintenance_form.paid_free.data,
number_of_days_deposited=maintenance_form.number_of_days_deposited.data,
scheduled_return_date=maintenance_form.scheduled_return_date.data,
return_processing_date=maintenance_form.return_processing_date.data,
returned_unreturned=maintenance_form.returned_unreturned.data
)
db.session.add(maintenance)
db.session.commit()
return redirect(url_for('index'))
else:
for fieldName, errorMessages in maintenance_form.errors.items():
for err in errorMessages:
app.logger.error(f'Error in {fieldName}: {err}')
except Exception as e:
app.logger.exception('Failed to register maintenance.')
return f'登録できませんでした。エラー: {e}'
return f'登録できませんでした。最初からやり直してください。'
これで実行すると、下記のとおりエラーログが表示されたので、原因がはっきりとしました(エラー部分の和訳は、「アプリでエラーが発生しました:date_of_receipt でエラーが発生しました:有効な日付値ではありません。」)。
[2024-03-07 10:03:50,704] ERROR in app: Error in date_of_receipt: Not a valid date value.
確認すると、下記のコードで、maintenance_form.date_of_receiptが重複していました。単純なコーディングミスです。
返却予定日をmaintenance_form.scheduled_return_date
返却(処理)日をmaintenance_form.return_processing_date
と、適切なフォームの変数に変更します。
<div class="form-group"
<label for="date_of_receipt">受付日:</label>
{{ maintenance_form.date_of_receipt(class="form-control", id="date_of_receipt", type="date") }}
</div>
<div class="form-group">
<label for="scheduled_return_date">返却予定日:</label>
{{ maintenance_form.date_of_receipt(class="form-control", id="scheduled_return_date") }}
</div>
<div class="form-group">
<label for="return_processing_date">返却 (処理)日:</label>
{{ maintenance_form.date_of_receipt(class="form-control", id="returnProcessingDate", type="date", required=false) }}
</div>
実行すると、新たなエラー
ERROR in app: Error in return_processing_date: Not a valid date value.
(ERROR in app:return_processing_date のエラー: 有効な日付値ではありません。)
これは、返却(処理)日が未入力なので発生しています。
この項目は、未入力でもOKにしたいので、そのように修正します。
以下、引用部分はリートンのテキストによる返答、コード部分はリートンが示した修正案
<div class="form-group">
<label for="return_processing_date">返却 (処理)日:</label>
{{ maintenance_form.return_processing_date(class="form-control", id="returnProcessingDate") }}
</div>
from wtforms.validators import Optional
class MaintenanceForm(FlaskForm):
# ... 他のフィールド ...
return_processing_date = DateField('返却 (処理)日', validators=[Optional()])
# ... 他のフィールド ...
該当箇所を修正して、実行しても、下記のようなエラーが出ます
リートンに説明を求めると
とのことだったので、このあと、return_processing_dateの値で試行錯誤、四苦八苦します。
ノートンで確認しても
と、エラーにならないはずだと言います。
そこで、該当箇所に日付を選択して送信してみました。
適切な値が送信されているはずなのに、また同じ下記のエラー
これは、違う場所だということに、ようやく気づきました。
エラーの原因特定に成功!!
今回のコードにDateで設定している箇所は、下記の3箇所
受付日
返却予定日
返却(処理)日
ここで気づきました!!
返却予定日は、自動計算して表示する「JavaScript」を設定しています。
ここだ!
と思い、forms.pyとmodels.pyを確認すると、
#forms.py
scheduled_return_date = StringField('Scheduled Return Date')
#models.py
scheduled_return_date = db.Column(db.Date, nullable=False)
と、forms.pyでは「StringField(文字列)」に設定して、models.pyでは「db.Date(日付)」で設定していました。
整合性が取れないので、エラーになっていたようです。
forms.pyを「DateField」に修正しました。
これで実行して、入力フォームに入力後に送信すると、無事に保存されました!!
これで、メンテナンス管理ページの新規登録ボタンがクリックされたあとの機能は実装されました。
次は、同ページの下記を実装していきます。
メンテナンス情報の更新
顧客検索
顧客検索結果の一覧表示
顧客一覧表示から任意のレコードを選択
選択した顧客idに紐づくメンテナンス情報の一覧表示
メンテナンス情報の一覧から任意のレコードを選択
メンテナンス情報の編集・更新
データベースへの保存
今日の体調
今日は、いつもどおりの倦怠感だけで、体調不良で引きこもりになって以降の体調でいうと、「マシ」な状態です。
こういう日は、作業をしていても、過集中になりがちです。
案の定、昼休憩をとらずにエラーの修正に躍起になってしまいました。
この記事が気に入ったらサポートをしてみませんか?