PosgtreSQLをpg_restore -c でリストアするとスキーマの権限が正しくリストアされない話

ただの備忘録。別にPostgreSQLに詳しいわけではない。

やったこと

pg_dump -d <hoge> -FtPostgreSQLのバックアップを取得 pg_restore -c -F t -d <hoge>PostgreSQLをリストアしようとした。

起こったこと

postgresのスキーマ(PUBLIC)に権限(privilages)がリストアされない。 -cもとい--cleanオプションを付けてprivilagesを削除しているので、リストアされたスキーマはprivilagesがない形になる。

スキーマのprivilegesがバックアップ前後で以下のように変わる*1

バックアップ前

全ロールにUSAGEとCREATEが付与されていた。

  name  |  owner   |  access privileges   |      description
--------+----------+----------------------+------------------------
 public | postgres | postgres=uc/postgres+| standard public schema
        |          | =uc/postgres         |

バックアップ後

一切の権限が付与されていない。

   Name  |  Owner   | Access privileges |      Description
 --------+----------+-------------------+------------------------
  public | postgres |                   | standard public schema

このためpostgresユーザ以外はスキーマへのアクセスができなくなる。 実際にはテーブル一覧を表示できなくなったり、スキーマ名を省略できなくなる。

オブジェクトへの権限がついていれば、明示的にスキーマを指定すればオブジェクトへアクセスはできるよう。 (schema.tablenameのように指定する)

なお、PUBLIC以外のスキーマで起こるかは未確認。

原因

詳細は不明なのだが、おそらくPostgreSQLバグ。

PostgreSQL: Re: BUG #14788: `pg_restore -c` won't restore schema access privileges.を参照すると同じような事象が報告されている。

上記では9.6.4だが、まだfixされているわけではないのだろう。

暫定対処

schemaに手動でGRANTする。PUBLICスキーマなら以下。

GRANT ALL ON SCHEMA public TO PUBLIC

その他

\dn+のアクセス権限の読み方が分からなかった。コマンド名で調べても情報がないが、ちゃんと大本のGRANTのドキュメントには記載があった。 困ったときはググるまえに公式ドキュメントをちゃんと読んだ方がよい。

*1:後述するメーリングリストからの引用

神崎洋治(2017)人工知能解体新書

人工知能がどういったもので、何ができるのか勉強する前ふりとして読んだ。

本としては悪くないと思うのだが、求めていた内容ではなかった。

本書はその内容の大半が実例だ。人工知能そのものの説明は2割あるかないかで、しかも体系だってはいない。

ビジネス向けの本、といったところで、いちおう科学向けの新書レーベルに期待していたものでば下さいはなかった。 (単に著者が想定した読者像と私にもがアンマッチだっただけなのだが)

Windowsの送る(SendTo)メニューでスラッシュ区切りのパス文字列をクリップボードにコピーする

概要

  • Windowsのパス文字列を他の言語に渡す際、円記号(¥)もといバックスラッシュ(\)を毎回処理するのが面倒
  • エクスプローラなどのGUIメニューで選択するときにスラッシュ(/)を区切り文字とする標準的なパス文字列を取得したい。
  • Powershellスクリプトを作成して、右クリックメニューの「送る(SendTo)」に登録することで簡単に取得できた。

背景

歴史的な経緯もあり*1Windowsのパスは円記号もといバックスラッシュ(\)区切り。

ただ、バックスラッシュはRやPythonといった各種プログラミング言語ではエスケープ文字として使われている。

このため、例えばRで以下のようにバックスラッシュが含まれるWindowsのパス文字列を直接利用できない。

#以下は動かない
> setwd("D:\SandBox\")
 エラー:  ""D:\S" で始まる文字列の中で '\S' は文字列で認識されないエスケープです

#以下のどちらかなら動く
> setwd("D:/SandBox/")
> setwd("D:\\SandBox\\")

大したことではないのだが、毎度バックスラッシュを処理して渡すのはめんどくさいので簡単にしたい。

方法

Windowsエクスプローラには、ファイル・フォルダの右クリックメニューの中に「送る(SendTo)」というメニューがある。

このメニューはSendToフォルダにあるショートカットの集合体であり、実行すると選択したファイル・フォルダを引数としてそのショートカットを起動してくれる。

そこで、エクスプローラ上で簡単にバックスラッシュをスラッシュに変換した文字列を取得するために、パス文字列を変換するスクリプトを作成してそのショートカットをSendToに登録した。
これでファイル・フォルダを右クリックしてショートカットを選択すると、スラッシュで区切られた文字列を取得できるようになる。

以下のようなGet-FilePathWithSlash.ps1を作成する。cf.Powershell上で、パイプで渡すと文字化けする。

$OutputEncoding = [System.Text.Encoding]::GetEncoding('shift-jis')
$args[0] -replace "\\", "/" | clip.exe

追記 2018-07-04

上記だとクリップボードに改行が入っていしまうのでPowershell5.0以上が入っている環境なら以下のようにした方が良い

$OutputEncoding = [System.Text.Encoding]::GetEncoding('shift-jis')
$args[0] -replace "\\", "/" | Set-Clipboard

SendToフォルダの場所を確認する。cf.【PowerShell】SendToフォルダを表示するスクリプト2 | ほそぼそプログラミング日記

#SendToフォルダの場所
[Environment]::GetFolderPath('SendTo')

Path
----
C:\Users\majima_ko16\AppData\Roaming\Microsoft\Windows\SendTo

上記のフォルダにショートカットを任意の名前で作成し、プロパティのリンク先を以下のように書き換える。 cf. 「送る」with PowerShell - なにか作る

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -WindowStyle Hidden -File "D:\<scriptPath>\Get-FilePathWithSlash.ps1"

その他

この方法を応用するとでCygwin用のパスも作れるだろう(cygpathはあるが)。

Powershellを使ってBasic認証を通してWebアクセスする

概要

  • PowershellInvoke-WebrequestのCredentialパラメータを使えば、簡単にBasic認証のかかったページにwebアクセスできる

実際

基本的に上記の通りCredentialを生成した上で、Invoke-Webreques-Credentialを指定してやればよい。 環境はWindows10で実行して試した、Powerhell 5.0以降であれば動作するはず。

その他

  1. ベーシック認証については以下を参照のこと

  2. Powershellを使って正しく認証プロキシ経由でWebアクセスする - mk_55's diaryでも記載したが、パスワードはSecureString等で事前に暗号化しておくことが望ましい。

Powershellを使って正しく認証プロキシ経由でWebアクセスする

概要

  • プロキシの自動構成スクリプト(.pac)に従って、正しい認証プロキシの認証を通した上で、Powershellでwebアクセスしたい。
  • つまり、アクセスするURLに対応するプロキシのURLを取得して、Invoke-Webrequestに渡してWebアクセスしたい。
  • [System.Net.WebRequest]::GetSystemWebProxy()を使うとOS設定を利用して、URLに対応するプロキシを取得することができる。

実際

OSでプロキシ設定がなされていることを前提としている

# 各種設定
$URL = "http://example.com"

# 認証情報の生成(本来は暗号化して外だししておく)
$ProxyUser = "User"
$ProxyPassword = "PassWord"
$securePassword = ConvertTo-SecureString $ProxyPassword -AsPlainText -Force
$proxyCredntial  = System.Management.Automation.PSCredential ($ProxyUser, $securePassword)

#システムのProxy設定を利用して、URLに対応するProxy経由でアクセス
$SystemProxy = [System.Net.WebRequest]::GetSystemWebProxy()
$proxy = $SystemProxy.GetProxy($URL)
Invoke-Webrequest $URL -Proxy $proxy.AsoluteUri -ProxyCredential $proxyCredntial  Method Get

環境はWindows10で実行しているので、Powerhell 5.0以降であれば動作するはず。

その他

  1. web上にはデフォルトプロキシを設定してしまうという例が散見されるが、汎用性に欠ける。

  2. プロキシの自動構成スクリプト(.pac)、要はJavascriptなので、ScriptControllerで実行してやろうと思った。しかし、ScriptControllerは64bit OSでは廃止されており不可能だった。

  3. 実用を考えるなら、パスワードはスクリプトに記載しせず、事前にSecureStringを利用してファイルに保存しておき、スクリプトの中でCredentialを生成する必要すべき。*1

  4. 例示用のドメインについてはRFC2606を参照のこと。

*1:正直なところ、私はSecureStringについて正しく理解しているとは言い難い。どこかで調べてまとめたい

携帯性だけを追求したBluetoothキーボード「Wekey Pocket PN301」

スマホ向けのキーボードを探していて、非常に薄くて軽いBluetoothキーボード「Wekey Pocket PN301」を購入したのでそのメモ。

良いところ

軽い。重さは95gとなんと100g以下である。

薄い。薄さは約5mmほど。

小さい。サイズはだいたいシステム手帳のバイブルサイズのリフィルぐらい。

上記のように携帯性が非常に良いので、気軽にカバンに入れておける。

また、二つ折りの本体を開くと電源が入り、すぐ使えるところも地味にポイントが高い。

悪いところ

キーボードとしての機能はあまり良くない。 打鍵感が全くないので、タイプの抜けがとても多い。また、ほぼただの板なので、タイピングは非常に固く長時間タイプするとだいぶ疲れそう。

その他

ペアリングはFn+P、キーサウンドはFn+BackSpaceで調整することができる。 キーボード配列が英語なので、気になる人は気になるかもしれない。

まとめ

メインで利用するというよりは、ちょっと外出・旅行するときに、スマホと一緒にお守り代わりに持っておくと重宝するかな、という感じだとおもう。

あと、似たような製品で以下のようなものがあり、重さが2倍になるが、打鍵感はこちらの方がよさそう。

WindowsのVS Codeでtextlintを使ってリアルタイムに文章校正する。

Windows上のVS Codeでtextlintを使うためにやるべきことは以下の通り。

Node.jsとnpmをインストールする

textlintはNode.js製のプログラムなのでまずはNode.jsとNode.js用のパッケージ管理ツールであるnpmをインストールする。

例えば次のようなページが参考になる⇒Node.js / npmをインストールする(for Windows) - Qiita

上記のページに従って、公式サイトにアクセスし、Windows用のバイナリをダウンロードしてインストールする。 インストールに成功していれば以下のコマンドでバージョンを確認できる。

PS D:\> node --version
v8.10.0
PS D:\> npm --version
5.6.0

textlintをインストールする

npmを使ってtextlintをインストールする。ここでは手っ取り早くグローバルインストールする*1

また、ルールを一から設定するのは手間なので、azuさん作の日本語の技術文書向けプリセットであるtextlint-rule-preset-ja-technical-writingをインストールする。 ついでに例外を明示するためにtextlint/textlint-filter-rule-commentstextlint/textlint-filter-rule-whitelistもインストールする。

PS D:\> npm install -global textlint textlint-rule-preset-ja-technical-writing textlint-filter-rule-comments textlint-filter-rule-whitelist

textlintを設定する

インストール後には設定ファイルを作成する必要がある。 textlintの対象にしたいフォルダへ移動してtextlint --initすると設定ファイルである.textlintrcが生成される。

PS D:\> cd D:\hoge
PS D:\hoge> textlint --init
PS D:\hoge> ls


    ディレクトリ: D:\hoge


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2018/03/23     22:53             34 .textlintrc
-a----       2018/03/23     22:06           1174 textlintのインストール.md

あとは生成された設定ファイルで、先ほどインストールしたプリセットルールを有効にする。

{
  "filters": {
      "comments": true
  },
    "rules": {
        "preset-ja-technical-writing": true
    }
}

トラブルシューティング

ここまでやって動くと思いきや、エラーでるのでそのトラブルシューティング

textlintが動作しない

[Error - 23:04:48] Server initialization failed.
  Message: Request initialize failed with message: Failed to resolve module: textlint
  Code: -32603

textlintへのパスが通っていないから発生したエラー。VS Codeを再起動して解決。

モジュールが利用できない

PS D:\Users\username\hoge> textlint --config .\.textlintrc .\textlintのインストール.md
× Error
Failed to load textlint's filter rule module: "comments" is not found.
See FAQ: https://github.com/textlint/textlint/blob/master/docs/faq/failed-to-load-textlints-module.md


× Stack trace
ReferenceError: Failed to load textlint's filter rule module: "comments" is not found.
See FAQ: https://github.com/textlint/textlint/blob/master/docs/faq/failed-to-load-textlints-module.md

    at TextLintModuleResolver.resolveFilterRulePackageName (C:\Users\username\AppData\Roaming\npm\node_modules\textlint\lib\textlint\src\engine\textlint-module-resolver.js:116:19)
    at TextLintModuleLoader.loadFilterRule (C:\Users\username\AppData\Roaming\npm\node_modules\textlint\lib\textlint\src\engine\textlint-module-loader.js:221:43)
    at C:\Users\username\AppData\Roaming\npm\node_modules\textlint\lib\textlint\src\engine\textlint-module-loader.js:80:23
    at Array.forEach (<anonymous>)
    at TextLintModuleLoader.loadFromConfig (C:\Users\username\AppData\Roaming\npm\node_modules\textlint\lib\textlint\src\engine\textlint-module-loader.js:79:32)
    at TextLintEngine.AbstractTextLintEngine (C:\Users\username\AppData\Roaming\npm\node_modules\textlint\lib\textlint\src\engine\textlint-engine-core.js:97:27)
    at new TextLintEngine (C:\Users\username\AppData\Roaming\npm\node_modules\textlint\lib\textlint\src\textlint-engine.js:22:47)
    at Object.executeWithOptions (C:\Users\username\AppData\Roaming\npm\node_modules\textlint\lib\textlint\src\cli.js:133:26)
    at Object.execute (C:\Users\username\AppData\Roaming\npm\node_modules\textlint\lib\textlint\src\cli.js:90:25)
    at C:\Users\username\AppData\Roaming\npm\node_modules\textlint\bin\textlint.js:34:20
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)
    at Function.Module.runMain (module.js:695:11)
    at startup (bootstrap_node.js:188:16)

commentsモジュールが見つからずに発生したエラー。再度全モジュールをnpm install -globalして解消。

コマンドラインでは動くけど、ファイルを開いても拡張機能が動作しない

textlintのVS Code拡張は以下の条件で動作するので、ファイル単位ではなく、フォルダ(プロジェクト)単位で開く必要がある。フォルダを開いて解決。

既に、textlintの設定をしているプロジェクト(node_modulesにtextlintやルールがインストールされていて、.textlintrcが配置されている場所)なら、VS Codeでそのディレクトリを開くだけで動作します。

VS Codeでtextlintを使って文章をチェックする - Qiita

指定のルールだけ設定を変更したい場合(2018/06/24追記)

‘preset-ja-technical-writing‘で一部のルールを無効化したり、設定を変更したりしたいときは、以下のように入れ子に記載する。

{
    "filters": {
        "comments": true
    },
    "rules": {
        "preset-ja-technical-writing": {
            "sentence-length": {
                "max": 100
            }
        }
    }
}

おわりに

ここまでできれば、リアルタイムにlintしながら文章を書くことができる。 ただ、この時点ではデフォルト設定がのみなので、効果は限定的だ。より効果を出すためには、 .textlintrc をカスタマイズして辞書やフィルタを育てていけばよい。 楽をするために頑張って、退屈なことは機械にやらせよう。

*1:Linuxなどにおいてインストールするときは、パーミッションエラー等になることもあるそうなので、よく考えてローカルモードでやった方がよいだろう