質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

SQLAlchemy

SQLAlchemyとはPython 用のORMライブラリです。MIT Licenceのオープンソースとして提供されています。

Q&A

解決済

1回答

1921閲覧

flaskでのテーブル内データの入れ替え方法

sandalwalk

総合スコア77

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

SQLAlchemy

SQLAlchemyとはPython 用のORMライブラリです。MIT Licenceのオープンソースとして提供されています。

0グッド

0クリップ

投稿2020/08/28 01:19

編集2020/08/28 04:49

flask(SQLAlchemy+postgresql)を使って、今週と来週分の予定表をweb上で表示するアプリを作成しています。以下の様なプログラムで来週の予定を今週の予定に一括変換をしたいのですが、このプログラムを実行すると、一旦は今週の予定画面に来週の予定が表示されますが、一旦他のページに移動し、再度今週の予定画面に戻ると、変更前の状態に戻ってしまします。commit() が原因かと思い、コメント部分の2行を追加してみましたが、この2行を追加すると、そもそも画面上の今週の予定画面は変化しなくなります。
一括でテーブル内のデータを入れ替える方法をご教示下さい。2つのテーブルの内容と行いたい事は以下の通りです。

今週の予定(テーブル名:this_week_schedule)=> プログラム実行前に表示されている内容
id=1, day="Monday", to_do="今週月曜日の予定"
id=2, day="Tuesday", to_do="今週火曜日の予定"
id=3, day="Wednesday", to_do="今週水曜日の予定"
id=4, day="Thursday", to_do="今週木曜日の予定"
id=5, day="Friday", to_do="今週金曜日の予定"

来週の予定(テーブル名:next_week_schedule)=> プログラム実行後に表示したい内容(既に情報は準備されている状態)
id=1, day="Monday", to_do="来週月曜日の予定"
id=2, day="Tuesday", to_do="来週火曜日の予定"
id=3, day="Wednesday", to_do="来週水曜日の予定"
id=4, day="Thursday", to_do="来週木曜日の予定"
id=5, day="Friday", to_do="来週金曜日の予定"
(2つのテーブル共に質問のプログラム実行前に既に全ての情報が保存されています)

行いたい事は、
*next_week_scheduleテーブルの内容をthis_week_scheduleテーブルに上書き保存(以下の様にしたい)
this_week_schedule
id=1, day="Monday", to_do="来週月曜日の予定"
id=2, day="Tuesday", to_do="来週火曜日の予定"
id=3, day="Wednesday", to_do="来週水曜日の予定"
id=4, day="Thursday", to_do="来週木曜日の予定"
id=5, day="Friday", to_do="来週金曜日の予定"
*その後、next_week_scheduleテーブルの内容は削除
*render_templateでindex.htmlに対して更新されたthis_week_scheduleテーブルの全データを渡す

python

1 2app = Flask(__name__) 3app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://localhost/testdb' 4db = SQLAlchemy(app) 5#中略 6 7class This_week(db.Model): 8 __tablename__ = 'this_week_schedule' 9 id = db.Column(db.Integer, primary_key=True, autoincrement=False) 10 day = db.Column(db.Text()) 11 to_do = db.Column(db.Text()) 12 13class Next_week(db.Model): 14 __tablename__ = 'next_week_schedule' 15 id = db.Column(db.Integer, primary_key=True, autoincrement=False) 16 day = db.Column(db.Text()) 17 to_do = db.Column(db.Text()) 18 19#中略 20 21@app.route('/update') 22@login_required 23def update(): 24 25 next_week = Next_week.query.all() 26 this_week = This_week.query.all() 27 28 this_week = next_week 29 30 db.session.add_all(this_week) 31 32 ''' 33 ここに以下の2行を追加すると、予定の入れ替え自体行えず、画面に変化無し 34 db.session.commit() 35 this_week = This_week.query.all() 36 ''' 37 38 return render_template('index.html', this_week = this_week) 39

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

FiroProchainezo

2020/08/28 02:41

やりたいことがよくわからないので、 This_weekのテーブルの内容と、Next_Weekのテーブルの内容を例示ください。 Next_weekの内容がこれで、This_weekの内容はこれ、Next_weekを一括変換(?)した後のテーブルの内容はこれ、の様に記載ください。 なお、追記は、質問文を編集してください。 ここに投稿されても回答者が見ない可能性があります。
guest

回答1

0

ベストアンサー

sandalwalkさんのコードを上から読むと以下を行っているようです。

  1. Next_weekを全取得
  2. This_weekを全取得
  3. 取得したthis_week変数の中身は何も使わず、next_weekで代入
    変数を代入しただけなので、DBには何もしていない
  4. this_weekを全部Insert
    たぶんIDが重複しているので入らない
    また、commit()は行っていないので、DBには何もしていない
  5. this_weekという名前で、index.htmlにthis_week変数(中身はnext_week)を返す

以下の手順でやると良いと思います。

  1. This_weekを削除
  2. Next_Weekの内容をThis_weekに書き込み
  3. Next_weekを削除

以下はその例です。
例ではMariaDBを使っていますので、適宜Postgreを使う様に読み替えてください。

python

1from flask import Flask, render_template 2from flask_sqlalchemy import SQLAlchemy 3 4 5app = Flask(__name__) 6 7app.config.from_object('config') 8 9app.config[ 10 'SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://{user}:{password}@{host}:{portnumber}/{database}?charset=utf8'.format( 11 user=app.config['SQL_USER_NAME'], 12 password=app.config['SQL_USER_PASSWORD'], 13 host=app.config['SQL_HOST_NAME'], 14 portnumber=app.config['SQL_PORT_NUMBER'], 15 database=app.config['SQL_DATABASE_NAME']) 16 17db = SQLAlchemy(app) 18 19 20class This_week(db.Model): 21 __tablename__ = 'this_week_schedule' 22 id = db.Column(db.Integer, primary_key=True, autoincrement=False) 23 day = db.Column(db.Text()) 24 to_do = db.Column(db.Text()) 25 26 27class Next_week(db.Model): 28 __tablename__ = 'next_week_schedule' 29 id = db.Column(db.Integer, primary_key=True, autoincrement=False) 30 day = db.Column(db.Text()) 31 to_do = db.Column(db.Text()) 32 33 34def data_add(): 35 data1 = This_week(id=1, day="Monday", to_do="今週月曜日の予定") 36 data2 = This_week(id=2, day="Tuesday", to_do="今週火曜日の予定") 37 data3 = This_week(id=3, day="Wednesday", to_do="今週水曜日の予定") 38 data4 = This_week(id=4, day="Thursday", to_do="今週木曜日の予定") 39 data5 = This_week(id=5, day="Friday", to_do="今週金曜日の予定" ) 40 41 data_2_1 = Next_week(id=1, day="Monday", to_do="来週月曜日の予定") 42 data_2_2 = Next_week(id=2, day="Tuesday", to_do="来週火曜日の予定") 43 data_2_3 = Next_week(id=3, day="Wednesday", to_do="来週水曜日の予定") 44 data_2_4 = Next_week(id=4, day="Thursday", to_do="来週木曜日の予定") 45 data_2_5 = Next_week(id=5, day="Friday", to_do="来週金曜日の予定") 46 47 db.session.add(data1) 48 db.session.add(data2) 49 db.session.add(data3) 50 db.session.add(data4) 51 db.session.add(data5) 52 db.session.add(data_2_1) 53 db.session.add(data_2_2) 54 db.session.add(data_2_3) 55 db.session.add(data_2_4) 56 db.session.add(data_2_5) 57 58 db.session.commit() 59 60 61@app.route('/show_this_week') 62def show_this_week(): 63 this_week = This_week.query.all() 64 65 return render_template('index.html', this_week=this_week) 66 67 68@app.route('/show_next_week') 69def show_next_week(): 70 next_week = Next_week.query.all() 71 return render_template('index.html', this_week=next_week) 72 73 74@app.route('/check_operation') 75def check_operation(): 76 next_week = Next_week.query.all() 77 this_week = This_week.query.all() 78 this_week = next_week 79 db.session.add_all(this_week) 80 db.session.commit() 81 return '' 82 83@app.route('/overwrite') 84def overwirte(): 85 next_week = db.session.query(Next_week).all() 86 this_week = db.session.query(This_week).all() 87 88 db.session.query(This_week).delete() 89 db.session.commit() 90 for n in next_week: 91 tmp = This_week(id=n.id, 92 day=n.day, 93 to_do=n.to_do) 94 db.session.add(tmp) 95 db.session.query(Next_week).delete() 96 db.session.commit() 97 98 99if __name__ == '__main__': 100 app.run() 101

html

1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6</head> 7<body> 8<div> 9 {% for n in this_week %} 10 {{ n.id }} 11 {{ n.to_do }} 12 <br /> 13 {% endfor %} 14 15</div> 16</body> 17</html>

python

1# config.py 2SQL_USER_NAME = 'root' 3SQL_USER_PASSWORD = 'password' 4SQL_HOST_NAME = 'localhost' 5SQL_PORT_NUMBER = '3306' 6SQL_DATABASE_NAME = 'teratail'

text

1$ pip freeze 2 3click==7.1.2 4Flask==1.1.2 5Flask-SQLAlchemy==2.4.4 6itsdangerous==1.1.0 7Jinja2==2.11.2 8MarkupSafe==1.1.1 9PyMySQL==0.10.0 10SQLAlchemy==1.3.19 11Werkzeug==1.0.1

投稿2020/08/28 06:10

FiroProchainezo

総合スコア2424

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sandalwalk

2020/08/28 06:40

アドバイスありがとうございます。まだ試せてないのですが、質問させて下さい。 頂いたpythonのコード中、def overwrite()の中のfor分の最後の部分にあるdb.session.add(tmp)ですが、この方法でどのテーブルに対してaddを行うか指定できるでしょうか。 想像ですが、def overwrite()では、for分の終わり部分までに使われるsessionはdb.session.query(This_week)だけなので、db.session.add(tmp)の行までに存在するsessionはThis_weekに対してのsessionだけなので、db.session.add(tmp)では自動的にThis_weekに対してaddが行われるという理解で正しいでしょうか?
sandalwalk

2020/08/28 07:41

回答頂いたpythonプログラムのdef overwrite()のfor分を抜けた所にcommit()を付か加えた所、問題なく動作しました。ありがとうございました。
FiroProchainezo

2020/08/28 08:27

tableを指定しているのか各classの__tablename__です。 > class This_week(db.Model): > __tablename__ = 'this_week_schedule' > class Next_week(db.Model): > __tablename__ = 'next_week_schedule' sessionがtableに対して接続しているようなニュアンスが見受けられますが、sessionはdb(MariaDBとかPostgreとか)に接続しているだけなので注意ください。 classがtableに、classの変数(idとか)が、各カラムにリンクしているようなイメージです。 python側ではclassを操作することにより、sqlalchemyが良い感じにdbを操作してくれます。 classは以下のように書く事もできるので、こちらの方が理解しやすいかもしれません。 class This_week(db.Model): __tablename__ = 'this_week_schedule' id = db.Column('id', db.Integer, primary_key=True, autoincrement=False) day = db.Column('day', db.Text()) to_do = db.Column('to_do', db.Text()) idはidにリンクし、dayはdayにリンクし、to_doはto_doにリンクします。 > 回答頂いたpythonプログラムのdef overwrite()のfor分を抜けた所にcommit()を付か加えた所、問題なく動作しました。 その部分にcommit()が無くても、最後にcommit()があるので動作していますが、何か勘違いしていませんか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問