redux-formでハマった話。
登録済みのデータをredux-formで編集する機能を作った時にハマった話。
プルダウン、テキストエリア、チェックボックス、チェックボックスに連動したプルダウン
(チェックボックスがONの時に表示されるプルダウン)
を入力項目として持つ画面に、変更機能を実装していた。
テキストエリアは、apiから取得したデータを初期値にセットできたが、
プルダウンが一向にでてこない。
色々調べまくったら、6系の時にそんなバグもあったような記事にたどり着く。
でも使ってるのは7.2
プルダウンだけのアクションを作ってやらないと、復元できないのか・・・・っと違和感たっぷりで
アクションを追加しようとした。
最初のプルダウンで問題が発覚していた、チェックボックス連動のプルダウンを確認していなかった。
ダメ元でチェックボックスが付いた状態になるデータで確認してみると・・・
ちゃんとチェックボックスもプルダウンの状態も復元できていた!
差分を確認しても、共通パーツ化しているので差分はなし!
APIの結果をみると・・・・
xxx:1
は復元できない
xxx:'1'
は復元できる
これってバグじゃないのか・・・・・
Big Query 入門
Big Queryについて
基本用語
- プロジェクト
課金をコントロールし、グローバルな名前空間のルート (BigQuery内のすべてのオブジェクトの名前は、プロジェクトに対する相対的な名前になる) - データセット
共有可能なテーブルの倫理的な集合をさす言葉。 データセットはプロジェクトに所有される。 - テーブル
リレーショナルデータベースと同様に、データの行の集合のこと ジョブ BigQueryが行う非同期な操作は、ジョブによって実行される。
プロジェクト(課金、トップレベルのコンテナ)
|
||
|
RESTコレクション
- Projects
BigQueryが有効になっている一覧を取れる(だけ)
Projects.list()
- Datasets
Datasetsはテーブルのコンテナ。 Datasetsコレクションは、insert()
、get()
、list()
、update()
、patch()
、delete()
のRESTfulなメソッドが用意されています。 - Tables
Tablesコレクションには、テーブルに関するメタデータが含まれます。
また、テーブルのデータには、アクセスすることはできません。 Tablesもinsert()
、get()
、list()
、update()
、patch()
、delete()
のRESTfulなメソッドが用意されています。 - TableData
TableDataコレクションは、テーブルのデータにアクセスするためのものです。 TableDataは、list()
とinsertAll()
が用意されています。 insertAllは、複数の行をテーブルに挿入するためのRPCメソッドです。 - Jobs
Jobsコレクションは、データの追加やクエリなど、BigQueryの「操作」を行うためのものです。
insert()
、get()
、list()
、query()
、getQueryResults()
が用意されています。
分割テーブル
既存のデータを移行したい場合は、下記のようなクエリで移行しかない? bq query --destination_table <project id>:<dataset>.<new table> --time_partitioning_field created_at --use_legacy_sql=false 'SELECT * FROM `<project id>:<dataset>.<old table>`'
ハマりどころ
gcloud config set project <PROJECT_ID>
で、big queryを使いたいプロジェクトを指定しておかないと、baコマンドがdefaultのプロジェクトに実行される。
Google App Engine(GAE) のdeployの話 Part3 ~デプロイに失敗しまくる話~
Google App Engine(GAE) のデプロイに失敗しまくる話
GAEで開発を進めていると、あるタイミングから急にデプロイに時間がかかりだし、ERRORでデプロイできない事業が繰り返される場合がある。
そんな時の対策を記載してみる。
cronを止めてdeployメモリの使用率をグラフで確認し、メモリをチューニング
CPUの数を増やす
resourcesの記述を消す
wokersのcpu * 2 + 1の指定をしている場合、少し減らすように変更する
傾向的に、pandasやjanomeなど、インストールに時間とCPUとメモリを消耗しそうなものを入れるときは、GCEより
かなり大きめのスペックが必要だなっという感じ。
数日前に、resourcesを消すとdeployできることが発覚。ただし費用面がまだ見えてない(2018/3/1 追記)
resourcesを決して実行すると(おそらく)最小構成でデプロイされます。
デプロイ失敗がつづいていたのは、一時的なものだったのかも?GCPUG slackでも同じ現象に陥ってる人がいたようですが、今はデプロイスムーズにできてます。(2018/3/20 追記)
あとは、コンテナイメージを作るとデプロイが早くなるらしいので、試してみるのもありかもです。
バッチ処理とかGCEで切り分けられるなら、分けちゃった方がコスト的にも良いかもしれない。
googleさん GAEのデプロイ失敗時に、なんで失敗してるのかを表示してほしい・・・・ (どこかのログでわかるのかな・・・?)
Google App Engine(GAE) のdeployの話 Part2 ~cron編~
Google App Engine(GAE) のcronの話
GAEでバッチ処理を行いたい場合は、バッチ処理の代わりにURLを叩いて処理します。
cron用のエンドポイントが必要になるってことですね。
そのエンドポイントをスケジュール登録して、叩いてもらう流れになります。
下記のように、cron.yamlを作成してdeployすることで、スケジュール設定することが可能です。
cron: - description: "バッチ1" url: /cron/sample_batch1/ schedule: every 15 minutes from 3:00 to 00:00 timezone: Asia/Tokyo - description: "バッチ2" url: /cron/sample_batch2/ schedule: every monday 01:00 timezone: Asia/Tokyo target: sample-api - description: "バッチ3" url: /cron/sample_batch3/ schedule: every day 08:30 timezone: Asia/Tokyo target: sample-api - description: "バッチ4" url: /cron/sample_batch4/ schedule: every 1 hours timezone: Asia/Tokyo target: sample-api
ハマりポイント
- GAEのタイムアウトについて最大60分と記述があります。
App Engine 環境の選択 | App Engine Documentation | Google Cloud
ですが、cronを実行してもworker timeoutと30秒ほどで異常終了となります。
回避策として、
app.yamlに
entrypoint: gunicorn --timeout 3600 -b :$PORT sample.wsgi
timeoutの指定が必要です。
・・・これかなりハマりました。。。
やりたかったけど、実現できなかったこと。
毎週月、火、水、木、金の、1時間毎で、08~20時まで
が、いろんなパターン試したが、deploy失敗・・・
結構需要あると思うんだけどなぁ・・・?
python djangoで画像をmodelのImageFieldに保存する時の話。
画像を保存する場合のお話。
- これに困った経緯
画像の保存先をgoogle cloud storageに保存したい。
これってどこでどうすれば保存できるんだ・・・から始まった。
静的保存場所の設定
- settingsにgoogle cloud storageの設定を追加
STATIC_URL = 'https://storage.googleapis.com/[プロジェクト名].appspot.com/static/' DEFAULT_FILE_STORAGE = 'storages.backends.gcloud.GoogleCloudStorage' GS_BUCKET_NAME = '[プロジェクト名].appspot.com' PROJECT_ID = '[プロジェクト名]'
を追加
- モデルにimageの定義
class Image(models.Model): img = models.ImageField(null=True, blank=True, upload_to='img')
import base64, request from django.core.files.base import ContentFile class ImageViewSet(ModelViewSet): queryset = Image.objects.all() serializer_class = ImageSerializer def create(self, request, *args, **kwargs): data = request.data.get('img') if data: format, imgstr = data.split(';base64,') ext = format.split('/')[-1] request.data['img'] = ContentFile(base64.b64decode(imgstr), name='temp.' + ext) return super(ImageViewSet, self).create(request)
URLから取得した画像を保存したい時
import request from .models import Image from django.core.files.base import ContentFile url = 'http://xxxxxxxxx/abc.jp' file_name = 'img/{}'.format(urlparse(url).path.split('/')[-1]) response = requests.get(url) image = Image() image.img.save(file_name, ContentFile(response.content, file_name), save=True)
Google App Engine(GAE) のdeployの話 Part1
Google App Engine(GAE) のdeployの話
GAE とは
Google App Engine (GAE) は、Googleの提供するサービスの1つであり、 ウェブアプリケーションをPHP・Python・Java・Go言語を使用して開発し、 Googleのインフラストラクチャー上で実行し、バージョン管理することができる。 Google Cloud Platformの一部。
※上記wiki抜粋
簡単に言うと、
開発したやつを簡単にデプロイできて、運用管理も楽チンだよ。 バージョン管理もできるし、異なるバージョンを同時に稼働させてABテストなんかもできちゃうんだよ
っという代物です。
GAE standard と flexible
GAEには、standardとflexibleがあります。
違いについてはオフィシャルを参考にしていただいた方が良いかと思います。
僕のpythonで経験した情報と所感を書いて見ます。
standard
pythonは2しか使用できません。
pip install を自分のプロジェクト内に展開しておいて、そのプロジェクト毎deploy(upload)する感じでした。
特に問題なさそうな話ですが、GAE内ですでに入っているパッケージなんかもあり、GAE環境に依存したパッケージの管理が必要になります。
レアケースかもしれませんが、deployしても、ソースの状態が反映されない(バージョンの向き先は最新になっているのに)問題が頻発しました。
flexible
pythonは2も3も指定できます。 pip モジュールは、requirements.txtに記載されているものをインストールしてくれます。 従来の構造のままdeployできる感じで、こちらの方がしっくりきました。 ソースが反映されないような問題にも直面せず、問題なさそうです。
ここからは先は、flexibleを採用したのでflexibleについての記載となります。
GAEのdeploy方法
app.yamlの記入例
runtime: python env: flex entrypoint: gunicorn -b :$PORT core.wsgi # ここの名前を変更する事で、同一のプロジェクト内に、複数のサービスとしてdeployできます。 service: sample-api runtime_config: python_version: 3 beta_settings: cloud_sql_instances: [プロジェクト名]:asia-northeast1:[db名] manual_scaling: instances: 2 resources: cpu: 2 memory_gb: 1.4 disk_size_gb: 10
- deploy コマンド
gcloudコマンドは、こちらからインストールする必要があります。
gcloud app deploy app.yaml --project [プロジェクト名]
上記コマンドを実行すると、時間はかかりますが簡単にdeploy完了です。