Rubyと筋肉とギターとわたし

エンジニア二年目の雑魚です。プログラミング・ギター・筋トレのことをメインにブログを書いていきます。

【PostgreSQL】CloudSQLからエクスポートしたダンプデータをインポートする

f:id:rdwbocungelt5:20181112160913p:plain

どうもてぃ。

最近エンジニア用のアカウントを作成しました。

写真チャラいです。

twitter.com

それはさておき、本番環境と同じデータをローカルに反映させたかったので、DBサーバーのCloudSQLからダンプデータを落としてローカルにインポートしました。

その時の流れを書きたいと思います。

プロジェクトはRailsです。

CloudSQLからCloudStorageへ

使用しているDBデータをCloudStorageへ落とします。

ここに手順を書いてもいいですが、googleのドキュメントのわかりやすさには勝てそうにないのでそちらを参考にしてください。

以下参考。

cloud.google.com

ローカルへインポート

CloudStorageから上記手順で落としたダンプデータをダウンロードします。

その後、psqlコマンドでDB名を指定してインポートします。

この際、先にDBを作って準備しておく必要があります。要注意。

$ bundle exec rails db:create

$ psql DB名 < ~/Downloads/Cloud_SQL_Export_2019~~~~~~~~~

ダウンロードしたダンプデータの保存先は基本Downloadsになっているはず。

違う場合はダウンロードしたパスを指定して上げてください。

ダンプデータのファイル名は上のように、 Cloud_SQL_Export_日付 になっているかと思うので、正しく指定してあげてください。

PG::ConnectionBad - fe_sendauth: no password supplied

準備が整ったと思ったので、サーバーを起動して画面確認したところ上記エラー。

単に database.yml でパスワード設定してないだけでした。

おろかなり。

PG::InsufficientPrivilege - ERROR: permission denied for relation schema_migrations

パスワードを設定して、サーバー起動後画面を表示するとこのエラー。

使用しているユーザーがDBスキーマに対して権限を持ってないとのこと。

以下で解決。

postgres=> \c <database_name>  # 権限を付与するDB名

database_name=> grant all on all tables in schema public to <user_name>  # user_nameは付与するユーザー名

\z で確認するとちゃんと付与されてるっぽかった。

マイグレーションを実行

$ bundle exec rails db:migrate
・
・
・

StandardError: An error has occurred, this and all later migrations canceled:

PG::InsufficientPrivilege: ERROR:  must be owner of relation <table_name>

まだ解決できない。。。

もっかい権限が付与されてるか確認してみると…特定のテーブルだけ権限が変更できてて、他は全く変更できてなかった。

\z じゃなくて、\d の方が見やすかった。だまされた。

なのでテーブルごとに権限を変更した。

postgres=> \c <database_name> 

# user_nameは付与するユーザー、old_user_nameは現在付与されているユーザー
database_name=> select 'alter table ' || schemaname || '.' || tablename || ' owner to <user_name>;'
from pg_tables
where tableowner = '<old_user_name>';

# 上で出てきたものをコピーして貼り付け実行する

すべてuser_nameをownerへ変更できた。

解決

マイグレーションがやっと通りました。

CloudSQLから落としたデータをインポートするとこんなにハマるとは思ってなかった。

今後同じようなことが出てくると思うので備忘録として、また同じような作業をする人へ向けて書きました。

なにかわからないことがあればコメントよろしくお願いします。

【vim】color pickerを使えるようにする

どうもてぃです。

VSCodeAtomでは標準で装備されてるcolor pickerですが、vimにはもちろんついてないです。

調べてみたら、普通にあったので導入してみました。

環境

  • Ubuntu 16.04.5 LTS(elementary OS 0.4.1 Loki)

vCoolor.vim

github.com

こちらですね。

僕は dein.vim をつかってパッケージ管理しているので、

" color picker
call dein#add('KabbAmine/vCoolor.vim')

を追加するだけ。

github上のREADMEにオプションが書いてあるので、必要であれば追記してください。

注意

github.com

上記URLの説明にある通り、

が呼び出されます。

Macの方は気にしなくていいですが、Linux & Windowsの方は気をつけてください。

完成

ノーマルモード:VCoolor と入力するとcolor pickerが呼び出されます。

f:id:rdwbocungelt5:20190606133650p:plain

呼び出すのを楽にしたいので後でキーマッピングしたいと思います。

では。

【Rails】helperで環境変数を使いたい場合

どうもてぃです。

備忘録として残しておきます。

環境変数を設定し、クライアント側で表示するものを変えたいとPMから要望が合ったので、その要件を満たすために実装しました。

実装したとはいっても、そんな大したことはやっていないですが。

実行環境

helperでは環境変数を読み込んでいない

まず前提として、helperでは環境変数は読み込めていないです。

今回、gemの dotenv-rails を使っていますが、設定していた環境変数をhelperやviewで呼び出したのですが、 nil が返ってきました。

module UsersHelper
  def display_user
    current_user.name if ENV['IS_USER_DISPLAY_DEFAULT'] == 'true'
    # => ENV['IS_USER_DISPLAY_DEFAULT']がnilで返ってくる
  end
end

こんな感じ。

.env ファイルに IS_USER_DISPLAY_DEFAULT を設定している状態です。

解決策

至って簡単。

helperのメソッド内で読み込み直せば良い。

module UsersHelper
  def display_user
    Dotenv.overload
    current_user.name if ENV['IS_USER_DISPLAY_DEFAULT'] == 'true'
  end
end

Dotenv.load では環境変数を変更した際に再読み込みされないようなので、 Dotenv.overloadで対応。

これで面倒なクライアントさんの要件を満たすことが出来ました。

めでたしめでたし。

【Rails】docker-composeでrails generateが使えず、Could not find rake ~~~~になる

どうもてぃです。

もうそろそろ梅雨ですね。ジメジメしたのは嫌いです。

今回は docker-compose を使って rails g controller を行うと起こるエラーの対処方法について書こうと思います。

環境

  • Docker version 17.12.0-ce, build c97c6d6
  • docker-compose version 1.20.1, build 5d8c71b

起こったこと

f:id:rdwbocungelt5:20190522160146p:plain

いつもどおり、Dockerfileとdocker-compose.ymlを作成し、イメージのビルド、サーバーの起動まで上手くいきました。

以下がDockerfileとdocker-compose.yml

FROM ruby:2.5
ENV LANG C.UTF-8
ENV APP_ROOT /myapp

RUN apt-get update -qq && \
    apt-get install -y build-essential libpq-dev nodejs postgresql-client && \
    rm -rf /var/lig/apt/lists/*
RUN gem install rails

WORKDIR $APP_ROOT
COPY Gemfile ${APP_ROOT}/Gemfile
COPY Gemfile.lock ${APP_ROOT}/Gemfile.lock
RUN bundle install --path vendor/bundle

ADD . /myapp
version: "3"
services:
  db:
    image: postgres
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: root
    ports:
      - "5432"
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -b 0.0.0.0 -p 3000"
    volumes:
      - .:/myapp
      - ./vendor/bundle:/myapp/vendor/bundle:delegated
      - /myapp/tmp/cache
      - /myapp/log
      - /myapp/vendor
      - /myapp/.git
    environment:
      RAILS_ENV: development
      DATABASE_HOST: db
      DATABASE_PORT: 5432
      DATABASE_USER: postgres
      DATABASE_PASSWORD: root
    ports:
      - "3000:3000"
    depends_on:
      - db
    tty: true
    stdin_open: true

ここにのせるとインデントがずれてますが、よくある構成だと思います。

上記の設定を元に環境を作ったあと、 rspec を導入したかったのでいつものコマンドを入力しました。

すると。。。

$ docker-compose run web bundle exec rails g rspec:install
Starting myapp_db_1 ... done
Could not find rake-12.3.2 in any of the sources
Run `bundle install` to install missing gems.

bundle installもうまくいくし、問題なさそうなのに Could not find rake-12.3.2 in any of the sources が出てくる。

対処法

stackoverflowで全く同じ質問していた人がいたので、参考にしてみた。

$ docker-compose run web bundle install --binstubs

# 自分の環境ではvendor/bundle配下に設置
$ docker-compose run web bundle install --path vendor/bundle

さて、ジェネレーターはちゃんと動くのか?

$ docker-compose run web bundle exec rails g rspec:install

Starting myapp_db_1 ... done
Beginning in Rails 4, Rails ships with a `rails` binstub at ./bin/rails that
should be used instead of the Bundler-generated `rails` binstub.

If you are seeing this message, your binstub at ./bin/rails was generated by
Bundler instead of Rails.

You might need to regenerate your `rails` binstub locally and add it to source
control:

 rails app:update:bin           # Bear in mind this generates other binstubs
                                # too that you may or may not want (like yarn)

If you already have Rails binstubs in source control, you might be
inadverently overwriting them during deployment by using bundle install
with the --binstubs option.

If your application was created prior to Rails 4, here's how to upgrade:

  bundle config --delete bin    # Turn off Bundler's stub generator
  rails app:update:bin          # Use the new Rails executables
  git add bin                   # Add bin/ to source control

You may need to remove bin/ from your .gitignore as well.

When you install a gem whose executable you want to use in your app,
generate it and add it to source control:

  bundle binstubs some-gem-name
  git add bin/new-executable

      create  .rspec
      create  spec
      create  spec/spec_helper.rb
      create  spec/rails_helper.rb
Usage:
  rails new APP_PATH [options]

Options:
      [--skip-namespace], [--no-skip-namespace]            # Skip namespace (affects only isolated applications)
  -r, [--ruby=PATH]                                        # Path to the Ruby binary of your choice
                                                           # Default: /usr/local/bin/ruby
  -m, [--template=TEMPLATE]                                # Path to some application template (can be a filesystem path or URL)
  -d, [--database=DATABASE]                                # Preconfigure for selected database (options: mysql/postgresql/sqlite3/oracle/frontbase/ibm_db/sqlserver/jdbcmysql/jdbcsqlite3/jdbcpostgresql/jdbc)
                                                           # Default: sqlite3
      [--skip-yarn], [--no-skip-yarn]                      # Don't use Yarn for managing JavaScript dependencies
      [--skip-gemfile], [--no-skip-gemfile]                # Don't create a Gemfile
  -G, [--skip-git], [--no-skip-git]                        # Skip .gitignore file
      [--skip-keeps], [--no-skip-keeps]                    # Skip source control .keep files
  -M, [--skip-action-mailer], [--no-skip-action-mailer]    # Skip Action Mailer files
  -O, [--skip-active-record], [--no-skip-active-record]    # Skip Active Record files
      [--skip-active-storage], [--no-skip-active-storage]  # Skip Active Storage files
  -P, [--skip-puma], [--no-skip-puma]                      # Skip Puma related files
  -C, [--skip-action-cable], [--no-skip-action-cable]      # Skip Action Cable files
  -S, [--skip-sprockets], [--no-skip-sprockets]            # Skip Sprockets files
      [--skip-spring], [--no-skip-spring]                  # Don't install Spring application preloader
      [--skip-listen], [--no-skip-listen]                  # Don't generate configuration that depends on the listen gem
      [--skip-coffee], [--no-skip-coffee]                  # Don't use CoffeeScript
  -J, [--skip-javascript], [--no-skip-javascript]          # Skip JavaScript files
      [--skip-turbolinks], [--no-skip-turbolinks]          # Skip turbolinks gem
  -T, [--skip-test], [--no-skip-test]                      # Skip test files
      [--skip-system-test], [--no-skip-system-test]        # Skip system test files
      [--skip-bootsnap], [--no-skip-bootsnap]              # Skip bootsnap gem
      [--dev], [--no-dev]                                  # Setup the application with Gemfile pointing to your Rails checkout
      [--edge], [--no-edge]                                # Setup the application with Gemfile pointing to Rails repository
      [--rc=RC]                                            # Path to file containing extra configuration options for rails command
      [--no-rc], [--no-no-rc]                              # Skip loading of extra configuration options from .railsrc file
      [--api], [--no-api]                                  # Preconfigure smaller stack for API only apps
  -B, [--skip-bundle], [--no-skip-bundle]                  # Don't run bundle install
      [--webpack=WEBPACK]                                  # Preconfigure for app-like JavaScript with Webpack (options: react/vue/angular/elm/stimulus)

Runtime options:
  -f, [--force]                    # Overwrite files that already exist
  -p, [--pretend], [--no-pretend]  # Run but do not make any changes
  -q, [--quiet], [--no-quiet]      # Suppress status output
  -s, [--skip], [--no-skip]        # Skip files that already exist

Rails options:
  -h, [--help], [--no-help]        # Show this help message and quit
  -v, [--version], [--no-version]  # Show Rails version number and quit

Description:
    The 'rails new' command creates a new Rails application with a default
    directory structure and configuration at the path you specify.

    You can specify extra command-line arguments to be used every time
    'rails new' runs in the .railsrc configuration file in your home directory.

    Note that the arguments specified in the .railsrc file don't affect the
    defaults values shown above in this help message.

Example:
    rails new ~/Code/Ruby/weblog

    This generates a skeletal Rails installation in ~/Code/Ruby/weblog.

rspecの設定ファイルは作成できたけど、なんかめっちゃ出てる。

要約するとbin関連をupdateしないといけないみたいね。ということでやってみた。

$ docker-compose run web bundle exec rails app:update:bin
# 以下全てOverwriteする

bin関連でOverwriteするかどうか出てくるので全て上書きでおk。

終わりに

念の為、controllerが作成できるか試してみた。

$ docker-compose run web bundle exec rails g controller Home index

特にエラーも警告もなくコントローラー生成できた\(^o^)/

二回も同じことで躓いたので、流石にメモ。

安易にdockerに頼り過ぎないようにしましょうね。

【Linux】xargsに渡したファイルに空白がある場合の削除方法

どうもてぃです。

ちょっとだけハマったのでメモ。

ls, grep, xargs rm

上記のコマンドを組み合わせて、いつもどおり溜まったスクリーンショット画像を削除しようとしました。

すると。。。

$ ls | grep 'Screenshot' |  xargs rm
rm: './Screenshot' を削除できません: そのようなファイルやディレクトリはありません
rm: 'from' を削除できません: そのようなファイルやディレクトリはありません
rm: '2019-05-08' を削除できません: そのようなファイルやディレクトリはありません
rm: '16-39-46.png' を削除できません: そのようなファイルやディレクトリはありません
rm: './Screenshot' を削除できません: そのようなファイルやディレクトリはありません
rm: 'from' を削除できません: そのようなファイルやディレクトリはありません
rm: '2019-03-14' を削除できません: そのようなファイルやディレクトリはありません
rm: '18-18-42.png' を削除できません: そのようなファイルやディレクトリはありません
rm: './Screenshot' を削除できません: そのようなファイルやディレクトリはありません
rm: 'from' を削除できません: そのようなファイルやディレクトリはありません
rm: '2019-04-18' を削除できません: そのようなファイルやディレクトリはありません
rm: '10-37-00.png' を削除できません: そのようなファイルやディレクトリはありません
rm: './Screenshot' を削除できません: そのようなファイルやディレクトリはありません
rm: 'from' を削除できません: そのようなファイルやディレクトリはありません
rm: '2019-03-12' を削除できません: そのようなファイルやディレクトリはありません
rm: '22-42-45.png' を削除できません: そのようなファイルやディレクトリはありません
rm: './Screenshot' を削除できません: そのようなファイルやディレクトリはありません
rm: 'from' を削除できません: そのようなファイルやディレクトリはありません
rm: '2019-03-07' を削除できません: そのようなファイルやディレクトリはありません
rm: '18-41-14.png' を削除できません: そのようなファイルやディレクトリはありません
rm: './Screenshot' を削除できません: そのようなファイルやディレクトリはありません
rm: 'from' を削除できません: そのようなファイルやディレクトリはありません
rm: '2019-04-16' を削除できません: そのようなファイルやディレクトリはありません
rm: '20-19-58.png' を削除できません: そのようなファイルやディレクトリはありません
rm: './Screenshot' を削除できません: そのようなファイルやディレクトリはありません
rm: 'from' を削除できません: そのようなファイルやディレクトリはありません
rm: '2019-05-06' を削除できません: そのようなファイルやディレクトリはありません
rm: '18-28-44.png' を削除できません: そのようなファイルやディレクトリはありません
rm: './Screenshot' を削除できません: そのようなファイルやディレクトリはありません
rm: 'from' を削除できません: そのようなファイルやディレクトリはありません
rm: '2019-03-01' を削除できません: そのようなファイルやディレクトリはありません
rm: '17-38-51.png' を削除できません: そのようなファイルやディレクトリはありません
rm: './Screenshot' を削除できません: そのようなファイルやディレクトリはありません
rm: 'from' を削除できません: そのようなファイルやディレクトリはありません
rm: '2019-03-12' を削除できません: そのようなファイルやディレクトリはありません
rm: '17-43-33.png' を削除できません: そのようなファイルやディレクトリはありません
rm: './Screenshot' を削除できません: そのようなファイルやディレクトリはありません
rm: 'from' を削除できません: そのようなファイルやディレクトリはありません
rm: '2019-03-06' を削除できません: そのようなファイルやディレクトリはありません
rm: '10-59-12.png' を削除できません: そのようなファイルやディレクトリはありません
rm: './Screenshot' を削除できません: そのようなファイルやディレクトリはありません
rm: 'from' を削除できません: そのようなファイルやディレクトリはありません
rm: '2019-03-26' を削除できません: そのようなファイルやディレクトリはありません
rm: '10-35-37.png' を削除できません: そのようなファイルやディレクトリはありません
rm: './Screenshot' を削除できません: そのようなファイルやディレクトリはありません
rm: 'from' を削除できません: そのようなファイルやディレクトリはありません
rm: '2019-04-28' を削除できません: そのようなファイルやディレクトリはありません
rm: '16-34-29.png' を削除できません: そのようなファイルやディレクトリはありません
rm: './Screenshot' を削除できません: そのようなファイルやディレクトリはありません
rm: 'from' を削除できません: そのようなファイルやディレクトリはありません
rm: '2019-04-04' を削除できません: そのようなファイルやディレクトリはありません
rm: '11-03-00.png' を削除できません: そのようなファイルやディレクトリはありません
rm: './Screenshot' を削除できません: そのようなファイルやディレクトリはありません
rm: 'from' を削除できません: そのようなファイルやディレクトリはありません
rm: '2019-02-08' を削除できません: そのようなファイルやディレクトリはありません
rm: '15-21-58.png' を削除できません: そのようなファイルやディレクトリはありません
rm: './Screenshot' を削除できません: そのようなファイルやディレクトリはありません
rm: 'from' を削除できません: そのようなファイルやディレクトリはありません
rm: '2019-01-25' を削除できません: そのようなファイルやディレクトリはありません
rm: '14-15-28.png' を削除できません: そのようなファイルやディレクトリはありません

ん???!!!??!?!?

前やった時こんなのでたっけ?状態になりました。

他にも、 find . -name 'Screenshot*' | xargs rmfind . -type f -name '*[Screenshot]*' | xargs rm 等も試してみましたが、ダメ。

結論

xargsコマンドは区切り文字に空白を使っているらしい。

つまり、空白の入ってるファイル名は別々のものと認識され、xargsに渡されてrmが実行されてしまうと。

そのため、区切りを空白文字ではなくnull文字で認識されなければいけないようです。

$ find . -name 'Screenshot*' -print0 | xargs -0 rm

xargsの -0 オプションの形式に合わせて、findコマンドで -print0 を指定してあげる。

これで解決しました。

【Ubuntu】LinuxならSequel ProのかわりにSqlectronを使おう

f:id:rdwbocungelt5:20190411003726p:plain

どうもてぃです。

新年度一発目の記事。そして平成最後の記事かもしれないです。

最近、副業を始めまして、お客さんの検証環境のDBにSSHでアクセスする機会がありました。

macで使ってたSequel ProをUbuntuにインストールして簡単にアクセスしようと目論んだのですが、サポートされていなかったので代わりのものを探していたところ、なんとありました!(つーか、CUIでアクセスすればいいんですけどね)

対象者

  • Ubuntu使用者でSQLGUIクライアントが使いたい方
  • Sequel Proみたいなのがほしい方
  • 無料でSQL GUIが使いたい方
  • 英語できる方

OS

  • elementary OS 0.4.1 Loki (Ubuntu 16.04.5 LTS)

探しまくったら意外とみつかった

ちゃんと公式まであるオープンソースっぽいですね

sqlectron.github.io

以下2つがGitHubリポジトリ

github.com

github.com

Termの方はあまり好みじゃなかったので、GUIの方をダウンロードしました。

以下がダウンロードページ。

github.com

.deb ファイルをダウンロードします。

f:id:rdwbocungelt5:20190411004618p:plain

最新の矢印のやつ。今回は 1.30.0 をダウンロードしてます。

ダウンロード先のパス(たぶんDownloadsだとおもう)でapt installしたらいけます。

$ sudo apt install ./Sqlectron_1.30.0_amd64.deb

でおk。

アプリケーションにアイコンが追加されているのがわかるかと思います

めっちゃ使いやすい

公式ページの中間辺りにあるgifを見ればわかるとは思いますが、シンプルでかなり使いやすいです。

英語だけど、苦手な方でも直感的にわかるかと思います。

Linux OSを使っている方、超絶必見です。是非使いましょう。

macユーザーの方

今がチャンスですよ。

【GCE】SendgridをGCPのlauncherで連携せずに使う

f:id:rdwbocungelt5:20180727094804j:plain

どうもてぃです。

今回は自分でアカウント登録したSendgridとGCEを連携させてメールを送信したいと思います。

準備

今回はGCP上のMarketplace検索すると使えるLauncherであるSendgridではなく、自分で登録したものを使います。

以下、リンク。

sendgrid.com

googleで検索すると上位には日本版Sendgridが出てきますが、これは使わないように。

というよりも、審査があってすぐには使えないのでとても不便。登録すると一瞬で使える本家(https://sendgrid.com)を使いましょう。

ここで、作成したAPIキーやら、usernameやらパスワードをしっかりメモっておくこと。

はまった

準備ができたら、公式に書いてある通りの順序でやっていきました。

cloud.google.com

僕はSendgridのAPIキーを取得して、それを/etc/postfix/sasl_passwdに設置しました。

Railsの本番環境を作っていてどうせAPIキーを使う予定だったので。

mailxでメール送信

設定を終えて、問題ないかmailxを使ってメール送信してみました。

# echo 'テストメールです' | mail -s 'テストめーる' mailaddress@gmail.com
# send-mail: 550 Unauthenticated senders not allowed

何故か送れない。

maillogも確認してみる。

# tail /var/log/maillog

Jan 21 05:09:09 instance-1 postfix/master[11145]: daemon started -- version 2.10.1, configuration /etc/postfix
Jan 21 05:09:40 instance-1 sSMTP[11153]: 550 Unauthenticated senders not allowed

ssmtpでの550が出てる。

対処法

Sendgrid公式に書いてありました。

今回は、GCPで予め用意されているものを使わず、自分で一から設定したので発生したのかも。

前やった時はGCPのSendgrid公式ドキュメントだけで問題なくいけたから。

sendgrid.com

ここで、/etc/ssmtp/ssmtp.confを設定すればおk。

ただし、今回はGCPなのでmailhub=smtp.sendgrid.net:587のポートを2525に変えてあげる。

正しくはmailhub=smtp.sendgrid.net:2525です。

解決!

いろいろ記事とか検索したけど、やっぱり公式ドキュメントを見るのが一番早いですね。

コマンドでメール送れたので、今度はRails側からも送ってみたいと思います。

ではでは。