質問編集履歴

3

一部解決したので追記

2019/06/25 09:05

投稿

akbr
akbr

スコア88

test CHANGED
File without changes
test CHANGED
@@ -20,6 +20,16 @@
20
20
 
21
21
 
22
22
 
23
+ 2019/06/25追記
24
+
25
+ 1.については解決したので解決方法を末尾に追記します
26
+
27
+ 2.については引き続き回答を募集中です
28
+
29
+
30
+
31
+
32
+
23
33
  ## 質問1
24
34
 
25
35
  まずversion_id_col機能自体についてですが、この情報を参考にmodel実装しました。
@@ -159,3 +169,177 @@
159
169
 
160
170
 
161
171
  よろしくお願いいたします。
172
+
173
+
174
+
175
+
176
+
177
+
178
+
179
+
180
+
181
+ ### 質問1の解決方法
182
+
183
+ 色々な記述方法を試していたら無事楽観的排他がかかりました。
184
+
185
+ 結局ネット上では答えが探せず、いろんなパターンを試しただけのため、良い方法なのかはわかりませんが。
186
+
187
+ 要点としては、
188
+
189
+ - version_id_colの指定は正しかった
190
+
191
+ - viewでpost後にmodelインスタンスを生成する際、dbからgetするのではなく空で作ってからmergeする
192
+
193
+ - versionをhiddenで持ちまわりたいがversionはintに対してhiddenにするとstrになってしまうので変換する
194
+
195
+
196
+
197
+ ※直接関係ないところは削除してるので多少矛盾があるかもしれませんご了承ください
198
+
199
+ ```python
200
+
201
+ models/sample.py
202
+
203
+ class BaseModelMixin(db.Model):
204
+
205
+ __abstract__ = True
206
+
207
+
208
+
209
+ @classmethod
210
+
211
+ def get(cls, pk):
212
+
213
+ return cls.query.get(pk)
214
+
215
+
216
+
217
+ @declared_attr
218
+
219
+ def id(cls):
220
+
221
+ return db.Column(db.Integer, primary_key=True)
222
+
223
+
224
+
225
+ def __repr__(self):
226
+
227
+ return 略
228
+
229
+
230
+
231
+
232
+
233
+ class VersionMixin(object):
234
+
235
+ version_id = db.Column(db.BigInteger, nullable=False)
236
+
237
+
238
+
239
+ __mapper_args__ = {
240
+
241
+ 'version_id_col': version_id,
242
+
243
+ }
244
+
245
+
246
+
247
+
248
+
249
+ class Sample(BaseModelMixin, VersionMixin):
250
+
251
+ __tablename__ = 'sample'
252
+
253
+ __table_args__ = {'extend_existing': True}
254
+
255
+ name = db.Column(db.String(length=255))
256
+
257
+ ```
258
+
259
+
260
+
261
+ ```python
262
+
263
+ forms/sample.py
264
+
265
+ class HiddenField(simple.HiddenField):
266
+
267
+ def populate_obj(self, obj, name):
268
+
269
+ if self.data == "":
270
+
271
+ data = None
272
+
273
+ elif isinstance(self.object_data, int):
274
+
275
+ data = int(self.data)
276
+
277
+ else:
278
+
279
+ data = self.data
280
+
281
+
282
+
283
+ setattr(obj, name, data)
284
+
285
+
286
+
287
+
288
+
289
+ class SampleEditForm():
290
+
291
+ id = HiddenField()
292
+
293
+ version_id = HiddenField()
294
+
295
+ name = StringField("名前", validators=[DataRequired()])
296
+
297
+ ```
298
+
299
+
300
+
301
+ ```python
302
+
303
+ views/sample.py
304
+
305
+ @bp.route('/<id>/edit/', methods=['GET', 'POST'])
306
+
307
+ def edit(id):
308
+
309
+ sample = Sample.query.get(id)
310
+
311
+ form = SampleEditForm(request.form, obj=sample)
312
+
313
+
314
+
315
+ if sample is None:
316
+
317
+ abort(404)
318
+
319
+ if request.method == 'POST':
320
+
321
+ if form.validate_on_submit():
322
+
323
+ sample = Sample()
324
+
325
+ form.populate_obj(sample)
326
+
327
+ db.session.merge(sample)
328
+
329
+ db.session.commit()
330
+
331
+ flash("保存しました", "success")
332
+
333
+ return redirect(url_for('.detail', id=sample.id))
334
+
335
+
336
+
337
+ flash("エラーがあります", "error")
338
+
339
+ return render_template('sample/edit.html', form=form)
340
+
341
+
342
+
343
+ return render_template('sample/edit.html', form=form)
344
+
345
+ ```

2

回答がつかないのとDB名誤っていたので修正

2019/06/25 09:05

投稿

akbr
akbr

スコア88

test CHANGED
File without changes
test CHANGED
@@ -1,12 +1,14 @@
1
- Flaskで開発中です。(Webアプリケーションはほとんど経験ありません)
1
+ Flaskで開発中です。
2
2
 
3
- 環境はWindows/Python3.7.0/flask1.0.3/MySQL5(xampp)です。
3
+ 環境はWindows/Python3.7.0/flask1.0.3/MariaDB(xampp)です。
4
4
 
5
5
 
6
6
 
7
7
  ### 実現したいこと
8
8
 
9
9
  Flask-SQLAlchemyで**楽観的排他処理**を実装しようとしています。
10
+
11
+ **回答がつかないようなので、もし回答がしづらい理由がある場合それをコメント頂けたらと思います**
10
12
 
11
13
 
12
14
 

1

回答が得られないのでタイトルを修正

2019/06/24 04:46

投稿

akbr
akbr

スコア88

test CHANGED
@@ -1 +1 @@
1
- Flask-SQLAlchemyでの楽観的排他処理実装方法について
1
+ Flask-SQLAlchemyでの楽観的排他処理実装方法がわかりません
test CHANGED
File without changes