CHANyoshiのブログ

初心者プログラマーです。

ubuntuでPostgreSQLの初期設定まで

設定に関しては、こちらを参考にしました。

PostgreSQL 9.6.5文書

UbuntuでPostgreSQLを使ってみよう (2) | Let's Postgres


まず、インストール

$ sudo apt-get install postgresql


データベースサーバにアクセスできるかどうか試験するため、データベースの作成をしてみる。

1.3. データベースの作成

$ creatdb mydb
createdb: could not connect to database template1: FATAL:  role "yoshi" does not exist


この表示は管理者がそのユーザー用のPostgreSQLユーザアカウントを作成していない時に起こるそう。 なので、まずアカウントを作成することにする。 21.1. データベースロール

fingerコマンドで『postgres』というアカウント が作成されていることを確認する。

$ finger postgres
Login: postgres                 Name: PostgreSQL administrator
Directory: /var/lib/postgresql          Shell: /bin/bash
Never logged in.
No mail.
No Plan.


確認できたら、postgresユーザでログインできるようにパスワードを設定する。

$ sudo passwd postgres
新しい UNIX パスワードを入力してください: 
新しい UNIX パスワードを再入力してください: 
passwd: パスワードは正しく更新されました


設定が完了し、postgres ユーザでログインできるようになった。
suコマンドでpostgresユーザーになり、 createdb コマンドでデータベースを作る

#mydbは任意の名前

$ su postgres
postgres@ubuntu:/home/yoshi$ createdb mydb


psqlコマンドでmydbに接続する

postgres@ubuntu:/home/yoshi$ psql mydb
psql (10.5 (Ubuntu 10.5-0ubuntu0.18.04))
Type "help" for help.

mydb=# 


mydbに入れたら、CREATE ROLE SQLコマンドで新規ユーザを作成し、データベースを操作できるようにする。

#nameは任意の名前(私はオペレーティングシステムユーザと同じ名前にしました)
#WITH LOGINを追加して、ログイン許可を与える

mydb=# CREATE ROLE name WITH LOGIN;
CREATE ROLE


PostgreSQLを切断し、さきほど設定した新規ユーザー(オペレーティングシステムユーザと同じ名前)で再度PostgreSQLに接続

mydb=# \q
postgres@ubuntu:/home/yoshi$ exit
$ psql mydb
psql (10.5 (Ubuntu 10.5-0ubuntu0.18.04))
Type "help" for help.

mydb=> 


無事、データベースに自分のアカウントでログインできるようになった。

【Python3】bitbank.cc APIより取得したビットコインのチャートデータをPostgreSQLに保存する②

前回データを整形するところまで終わったので、今度は テーブルの作成をする。
PostgreSQLのセットアップは終わっているものとする。

float型のデータはdouble precision、
datetime.datetime型のデータはtimestamp without time zoneを指定した。

$ psql mydb      ←データベースにmydbを指定してpsqlを起動


--テーブルを作成--
mydb=> CREATE TABLE bitbank
mydb-> (high double precision ,
mydb(>  sell double precision ,
mydb(>  buy double precision ,
mydb(>  last double precision ,
mydb(>  timestamp timestamp without time zone ,
mydb(>  low double precision ,
mydb(>  vol double precision ,
mydb(>  PRIMARY KEY (timestamp));

NOTICE:  CREATE TABLE / PRIMARY KEYはテーブル"bitbank"に暗黙的なインデックス"bitbank_pkey"を作成します
CREATE TABLE
--テーブルの項目を確認--
mydb=> \d bitbank

             テーブル "public.bitbank"
    列     |             型              |  修飾語  
-----------+-----------------------------+----------
 high      | double precision            | 
 sell      | double precision            | 
 buy       | double precision            | 
 last      | double precision            | 
 timestamp | timestamp without time zone | not null
 low       | double precision            | 
 vol       | double precision            | 
インデックス:
    "bitbank_pkey" PRIMARY KEY, btree ("timestamp")


ここまでの一連の流れ(前回記事①含め)を.pyファイルにまとめたもの。
冗長ですが許してね。

#bitbank.cc APIからデータを取得

import requests
import simplejson as json
from datetime import datetime
base_url = "https://public.bitbank.cc"
api_urls = {'ticker':'/btc_jpy/ticker'}

class Public(object):
    def __init__(self):
        pass


    def public_api(self,url):
        ''' template function of public api'''
        try :
            url in api_urls
            return json.loads(requests.get(base_url + api_urls.get(url)).text)
        except Exception as e:
            print(e)


    def getticker(self):
        '''Ticker を取得'''
        return self.public_api('ticker')

P=Public()
a=P.getticker()




#dictに必要な部分のデータを保存
dict = a['data']

timestamp = str(dict['timestamp'])

a = timestamp[:10]
b = timestamp[10:]
c = "."

dict['timestamp'] = a + c + b
dict['timestamp']= float(dict['timestamp'])
dict['timestamp'] = datetime.utcfromtimestamp(dict['timestamp'])

dict['high'] = float(dict['high'])
dict['sell'] = float(dict['sell'])
dict['buy'] = float(dict['buy'])
dict['last'] = float(dict['last'])
dict['low'] = float(dict['low'])
dict['vol'] = float(dict['vol'])


#PostgreSQLに接続
import psycopg2
connection = psycopg2.connect("host=localhost port=5432 dbname=mydb user=yoshiaki password=69SK6X0O")

#conneection.cursor()をcurに代入
#cursorオブジェクトをconnection.cursor()で取得する。
cur = connection.cursor()


#APIより取得したデータをデータベースに保存(PostgresSQL)
cur.execute(
    "INSERT INTO bitbank (high, sell, buy, last, timestamp, low, vol) VALUES (%s, %s, %s, %s, %s, %s, %s);"
    ,(dict['high'], dict['sell'], dict['buy'], dict['last'], dict['timestamp'], dict['low'], dict['vol'])
)


#トランザクションをコミットする
connection.commit()


#クローズする
cur.close()


ターミナルで実行(ファイル名:APIデータ(bitbank)→PostgreSQL.py)

$python3 APIデータ(bitbank)→PostgreSQL.py


.pyファイル実行ごとにデータが追加されることを確認

mydb=> SELECT *
  FROM bitbank;
  high  |  sell  |  buy   |  last  |        timestamp        |  low   |   vol   
--------+--------+--------+--------+-------------------------+--------+---------
 450001 | 438350 | 434200 | 436275 | 2017-09-20 09:03:22.862 | 423943 | 17.5622
 450001 | 438348 | 434200 | 436274 | 2017-09-20 09:14:16.193 | 423943 | 17.5666
 446386 | 435609 | 433000 | 435609 | 2017-09-20 11:43:08.626 | 423943 | 16.0655
 446386 | 435609 | 431364 | 433486 | 2017-09-20 11:48:47.766 | 423943 | 16.0669
(4 行)


あとは実際にデータを使いながら、適宜調整していく予定。
定期的に実行する場合は、

chanyoshi.hatenablog.com

に少しまとめました。

終わり。

【Python3】bitbank.cc APIより取得したビットコインのチャートデータをPostgreSQLに保存する①

ざっくりと。
まず、取得した辞書データ

{'high': '489000', 'sell': '443000', 'buy': '439000', 'last': '441000', 'timestamp': 1505830555602, 'low': '425000', 'vol': '29.1356'}


値の型を確認

for t in dict.values():
    print(type(t))

<class 'str'>
<class 'str'>
<class 'str'>
<class 'str'>
<class 'int'>
<class 'str'>
<class 'str'>

#timestampだけint型。その他はstr型。


timestampはUTCでデータベースに保存したい。 現在、unixtimeなので、UTCに変換する。 下記ブログを参考にしました

Python 3 で少しだけ便利になった datetime の新機能 - Qiita

from datetime import datetime
utc = datetime.utcfromtimestamp(dict['timestamp'])
utc






---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-62-df88e9c4d9de> in <module>()
      1 from datetime import datetime
----> 2 utc = datetime.utcfromtimestamp(dict['timestamp'])
      3 utc

ValueError: year is out of range

エラーが出た。よく見ると数字の桁数が多い?
unixtimeの詳細について以下記事が参考になりました。
今は秒数部分は10桁で表すらしい。

UNIXTIME - 日付・時刻の徹底解説

エラーの原因としては小数点が打たれてないことが問題っぽい。
整数型で位置を指定して小数点を追加する方法がわからなかったので、一度文字列型にして小数点を追加する

timestamp = str(dict['timestamp'])

a = timestamp[:10]
print(a)

b = timestamp[10:]
print(b)

c = "."

dict['timestamp'] = a + c + b
print(dict['timestamp'])
print(type(dict['timestamp']))




1505830555
602
1505830555.602
<class 'str'>


できた。文字列だとUTCに変換できないので、浮動小数点に変換し、挿入する。

from datetime import datetime

dict['timestamp']= float(dict['timestamp'])
dict['timestamp'] = datetime.utcfromtimestamp(dict['timestamp'])

print(dict['timestamp'])
print(type(dict['timestamp']))


2017-09-19 14:15:55.602000
<class 'datetime.datetime'>


UTC時間だから日本時間-9時間の値が出てくる。
データ型はdatetime.datetimeでした。
あとは、残りの辞書データを浮動小数点に変換する。(for文ですべて変換してからtimestampをいじればよかったのだが、最初にやってしまったので1つ1つやる)

dict['high'] = float(dict['high'])
dict['sell'] = float(dict['sell'])
dict['buy'] = float(dict['buy'])
dict['last'] = float(dict['last'])
dict['low'] = float(dict['low'])
dict['vol'] = float(dict['vol'])

for t in dict.values():
    print(type(t))
print(dict)


<class 'float'>
<class 'float'>
<class 'float'>
<class 'float'>
<class 'datetime.datetime'>
<class 'float'>
<class 'float'>

{'high': 489000.0, 'sell': 443000.0, 'buy': 439000.0, 'last': 441000.0, 'timestamp': datetime.datetime(2017, 9, 19, 14, 15, 55, 602000), 'low': 425000.0, 'vol': 29.1356}

無事、timestamp以外floatになりました。

さくらのVPS(CentOS 7)にubuntu16.04LTSでSSH接続する

さくらのVPS上にCentOSをインストールした後、 サーバにログインする

下の記事を参考にしました。 vps-news.sakura.ad.jp

ターミナルにて、

$ ssh root@<IPアドレス>  ←接続先サーバのIPアドレスを入力


sshのデフォルトでは、未知のホスト鍵に対しては、ユーザーに確認を求める。 yes をタイプしてenter。

The authenticity of host '000.000.000.000 (000.000.000.000)' can't be established.
RSA key fingerprint is 11:22:33:44:55:66:77:88:be:d0:ca:61:52:6f:ad:d8.
Are you sure you want to continue connecting (yes/no)?


パスワードの入力をうながされるので、パスワードを入力する

コマンド待ちの#記号が最後に表示されればログインの完了。

cronを設定してpythonプログラムを定期的に実行する

cronで定期的にpythonスクリプトを実行する。


cronを起動する(既に起動している場合が多いが)

sudo /etc/init.d/cron start
[ ok ] Starting cron (via systemctl): cron.service.


cronの設定ファイルを開き、コマンドを実行する時間を設定する。

crontab -e

一番下の行まで移動し、 設定を記述する。

以下は設定例の一覧
こちらのページからお借りしました
決まった時間に処理する | Make.

分 時 日 月 曜日 コマンド

#毎日6時にプログラムを実行する
00 6 * * * python /home/hoge/script1.py
  
#毎時10分にプログラムを実行する
10 * * * * python /home/hoge/script2.py
  
#15分毎にプログラムを実行する
*/15 * * * * python /home/hoge/script2.py
  
#毎月20日10:00にプログラムを実行する
00 10 20 * * python /home/hoge/script3.py
  
#毎週月曜日10:00にプログラムを実行する
00 10 * * 1 python /home/hoge/script4.py
  
#cronでプログラムが動かない場合
2分毎にプログラムを実行し、エラーログを確認する
*/2 * * * * python /home/hoge/script5.py 2> /home/hoge/script5.log


私は5分おきに定期的に実行したかったので、

*/5 * * * * python /home/hoge/script2.py

としたのだが、エラーが出た。 調べてみたら、どうもパスが通ってないらしい。
pyenvでバージョン管理をしている人は、パスの通し方を工夫しなくてはいけらしい。

以下記事を参考にしました
【Python】cronでpyenv環境のPythonが実行されない時の対処法 – あずみ.net

まず、以下コマンドでコマンドのフルパスを表示させる

which python3
/home/hoge/.pyenv/versions/anaconda3-4.2.0/bin//python3


次にさきほどのcron設定内容を変更する

*/5 * * * * python /home/hoge/script2.py
↓
*/5 * * * * /home/hoge/.pyenv/versions/anaconda3-4.2.0/bin//python3 /home/hoge/script2.py

python部分をpyenv環境のPython実行ファイルのパスに変更した。

これで定期的に起動するはず。

virtualenvのインストール、使い方

ubuntuにvirtualenvをインストールし、その上でdjangoを起動させようと思う。

virtualenvのインストー

$ pip install virtualenv



仮想環境の作成。
仮想環境を作りたい場所にcdし、以下のコマンドで、仮想環境を作成。

$ cd
$ virtualenv my_env  ←my_env部分は任意の仮想環境名をつける



仮想環境は作成しただけでは有効にならないため、 以下のようにして有効化する。

$ source my_env/bin/activate
# コンソール上に、以下のように表示されれば成功。
(my_env) $ 



仮想環境の無効化・削除は それぞれ、以下のようにする。

# 仮想環境の無効化
(my_env) $ deactivate

# 仮想環境の削除
# (プロジェクト直下に生成されたフォルダを、まるごと削除する。)
$ rm -rf my_env/

virtualenv上にDjango(最新版)をインストールする

仮想環境my_envを有効化する(my_envは任意につけた名前)

$source my_env/bin/activate
(my_env) $ 



最新の公式バージョンは1.11.3だそう。 バージョンを指定してDjangoをインストールする。

(my_env)$pip install Django==1.11.3



正しくインストールされたか、 pip freeze コマンドで確認。Django==1.11.3と表示されていれば成功。

(my_env)$pip freeze
Django==1.11.3
pytz==2017.2



できた。