チャットを作りたい① Apacheとnginxの共存

チャットを作りたい

やり方は色んなのがあるみたいで、調べた中ではポーリングとかWebSocketとかがあった。で、WebSocketが良さげな感じがした。WebSocketの実装するにあたってどれがいいかなーと思って、例えばWikipedia見ると

https://ja.wikipedia.org/wiki/WebSocket

サーバー欄に色々書いてる。あとは「チャット 開発」とかでググったりすると色んなのが出てくる。その中でNode.jsっていうのがよさそうだったのでそれ使ってみたい。

なんだけど、Node.jsでアプリ作って実行すると、ターミナルが実行中のままになってCtrl+Cするまでずっとコマンド打てない感じになる。今このブログが置いてあるサーバーはCentOS+ApacheなんだけどApacheはそんなことない。起動したら裏で動いててくれて、ターミナルで他のことができる。そういう感じにしたい。できるのかなーと、どういう仕組なんだろうなーと、調べるとサービスとかデーモン化とかすると裏で動く感じになるみたい。Node.jsにはそれ用のライブラリがあって、foreverっていうらしい。それ使えばできそう。

あと、ApacheもNode.jsもサーバーの機能が被ることになる。競合して変ななりそうな気がする。かといって練習のためだけにまた新しく費用かけてインスタンス建てるのもなーと考えてた。これも調べていくとリバースプロキシっていうのがあって、リクエスト先によって、ApacheとNode.jsのどっちで処理するか振り分けるみたいなことができるらしい。でも難しそう・・・。で、リバースプロキシが得意なサーバーがあって、nginxという。nginxとApacheもリバースプロキシを使って共存ができるみたいで、Node.jsとも共存ができるらしい。ほほう。つまりReq→Nginx→Apache or Node.js(forever)っていう感じになれば、1つのサーバーで完結できそう。できるんですか?

頭の中ではこんな感じなのだが、じゃあこれをやれるのかと。とりあえずやってみよう。失敗したらブログも消えてさよならですね。

ブログのバックアップを取る

ブログ消えるのヤなので、バックアップをとっとく。

https://ja.wordpress.org/plugins/all-in-one-wp-migration/

時々このプラグインでバックアップを取っている。色んな更新が溜まってたので、それも適用してからローカルにダウンロードしといた。これで最悪全部ぶち消えても大丈夫だ。大丈夫だよね?

NginxとApacheを共存させる

https://qiita.com/mike-ayumu/items/5f255bab07606759a8e5

https://qiita.com/skxeve/items/a20ca4baa027c5d48318

https://designsupply-web.com/media/developmentlab/3466/

https://www.logw.jp/cloudserver/8516.html

などのいろんな記事を参考に、Nginxをインストールして設定してく。

準備

cloudflareを一時停止する

ResponceHeaderがcloudflareになってるのが

Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/7.3.4になった。

Apacheを止める

$ systemctl stop httpd

で止まる。

Apacheのポート番号を変更

/etc/httpd/conf/httpd.confへ行き

Listen 80
を
Listen 8080

に変更。この番号は使ってないやつだったら何でもいいみたい。SSLはLet’s encryptを使ってるけどやり方がわからん。

https://t-tel.net/ssl/ssl061/
を見て
/etc/httpd/conf/httpd.confに
Listen 8443
を追記。

これダメだった。

/etc/httpd/conf/httpd-le-ssl.confの

<VirtualHost *:443>

<VirtualHost *:8443>
に変更した。

$ service httpd configtest

てすると

Syntax OK

は出る。で、試しに

$ systemctl start httpd

でサイトにアクセスしてみるとプライバシエラー。ただまぁ無視して突き進むと表示できた。(保護されていない通信って赤字は出る。)

うーむ、ちょっとよく分かんないのでとりあえず突き進もう。

$ systemctl stop httpd

でApache止める。

nginxインストール

普通にインストールしようとすると古いバージョンが入ってしまうそうなので、リポジトリを追加する。

/etc/yum.repos.d/に行って

$ vi nginx.repo

とか。でCentOS7.4なので

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1

こう。んで保存。そしたら

$ yum install nginx

確認。

$ nginx -V
nginx version: nginx/1.18.0

大丈夫そう。

$ systemctl start nginx

起動。

$ systemctl status nginx

チェック。

Active: active (running)

うむ。そんで

!http://dalomo.net/に行くと

表示された!けど

!https://dalomo.net/だと表示されない。。。まぁおっけおっけー。一応

$ systemctl enable nginx

で自動起動されるようにしとく。

$ systemctl restart httpd

でApache再起動。

nginxの設定ファイルを編集する

/etc/nginx/conf.d/に行って、default.confはリネームしちゃう。

$ mv default.conf default.conf.bak

そんで新たにファイル作る

$ vi reverse_proxy.conf

設定ファイルの書き方がいまいちわかんないなぁ、まず

server {
    listen 80;
    server_name localhost;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

だけ書いて保存。んでnginxを再起動

$ systemctl restart nginx

そしたら502 Bad Gatewayになる。。。うーん?

ここでちょっと席外してたらいつの間にかアクセスできるようになってた。なんだったんだろ。ただそれでもプライバシエラーは出るし、ResponceHeaderはApacheのままだ。ちょっとnginxのlogを見てみると

connect() to 127.0.0.1:8080 failed (13: Permission denied) while connecting to upstream

ってエラーが出てた。

https://qiita.com/wataru420/items/f3ddbce206f2eb2b5d27

https://tech.mktime.com/entry/447

を参考に

$ setsebool httpd_can_network_connect on -P

と打ったらエラーは出なくなった。でもサイトにアクセスしても特に変わりがない・・・。証明書がなんか変になってんのかなーと思った。まずはポート443の設定も追記してみる。

server {
    listen 443;
    ssl on;
    ssl_certificate /etc/letsencrypt/live/dalomo.net/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/dalomo.net/privkey.pem;
    server_name localhost;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

the "ssl" directive is deprecated, use the "listen ... ssl" directive instead in

て出たので

http://manualkun.com/warn_ssl/2/

listen 443 ssl;
ssl on; #削除

した。

ちゃんと表示されるように頑張る

なんやかんやあってApacheが再起動できなくなった。調べてくと上で編集した

/etc/httpd/conf/httpd.confに

Listen 8443

じゃなくて、/etc/httpd/conf.d/ssl.confを編集するべきだったみたい。

上の追記を削除して

https://designsupply-web.com/media/developmentlab/3466/

こちら参考に

Listen 443 https
→ Listen 8443 https
<VirtualHost _default_:443>
→ <VirtualHost _default_:8443>

こう変えたら起動した。ポート443がnginxと被ってたってわけだ。そんでアクセスしてみると

dalomo.net でリダイレクトが繰り返し行われました。
ERR_TOO_MANY_REDIRECTS

になった。これも上記ページを参考に

RewriteEngine on
RewriteCond %{SERVER_NAME} =dalomo.net [OR]
RewriteCond %{SERVER_NAME} =dalomo
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

にしてたのをすべてコメントアウト。そしたら再起動を忘れずに

$ systemctl restart httpd
$ systemctl restart nginx

したらちゃんと表示された。

おー!ちゃんと表示されたわ!

ちゃんとnginxになってる!長かったぜ~

カテゴリー: したい | タグ: , , , | コメントする

ミッドナイトスワン面白かった

https://midnightswan-movie.com/

泣きたいなーと思って見に行ったけど正解だった。原作あるんね、原作は見てない。

今の映画館って座席1個ずつ開けるんですね。両隣の人も鼻すすってた。

草彅剛さんの演技はそこまで好きじゃないんだけど、それでもよかった。

ていうか演者さん全員良かった。

水川あさみのアバズレ役って超ハマるよね。でも、彼女は彼女で愛があった。

設定はよくあるやつだとは思うんだけど、そこにLGBT、ネグレクトの設定もあって作品の個性が立ってるなーと思う。すげー上からですね、すみません。

音楽もいいし、映像もすごくいい。久しぶりに映画見たーって感じになった。

2人の関係性の深まりをもうちょっと描き込んでほしかったなーとは思ったかな、でも、バレエの先生が凪沙をお母さんと呼んでしまう所でなんか泣いた。これは予告見てたのもあったけど。

他にもいっぱい泣いた。スッキリしたー。

カテゴリー: のーと | タグ: , | コメントする

データベースを使ったサイトを作りたい⑨ ちょこちょっこ変更

まいにち詰将棋の検索サイト

基本的な機能はできたので、思いついたことをやってってみる。

https://dalomo.net/shogi/form.php

更新日を記載

require ('config.php');

  try {
    $pdo = new PDO($dsn, $user, $password);
  } catch (PDOException $ext) {
  }

  $sql = "SELECT MAX(date) FROM data";
  $state = $pdo->prepare($sql);
  $state->execute();
  $res = $state->fetch(PDO::FETCH_ASSOC);
  
  $latestday = $res["MAX(date)"];

  $pdo = null;

こんなん書いて、更新日表示するようにした。

metaタグ

スマホで見るとめっちゃ小さい

<meta name="viewport" content="width=device-width,initial-scale=1.0">

これ書いたらある程度の大きさで表示されてくれた。

スマホでよく見るアドレスバーの色が変わるやつ

<meta name="theme-color" content="#864944">

小豆色にした。

chromeで見ると翻訳ダイアログが出るし、元言語が中国語

<meta name="google" content="notranslate">

一応出なくなったっぽい。

tableタグの枠線?罫線?の太さを変える

今までは

<table border="1">

で指定してたけどHTML5じゃ廃止されてCSSで指定するみたい。CSSわかんないからコピペる。headタグ内に書くみたい。

https://htmlcss.step-learn.com/contents/c029-table-border-weight.html

<style>
    table {
    border-collapse: collapse;
    }
    th {
        border: 1px solid black;
    }
    td {
        border: 1px solid black;
    }
</style>

線1本になった。

ファイルの一覧(Index of /)が丸見えだった

index.htmlを置こうかなと思ったら、index.phpでもいいらしい。更にPHPにはリダイレクトの機能を作ることもできるらしい。.htaccessとかでもできるそうだけどせっかくなのでPHPで書いてみると

<?php
header('Location: https://dalomo.net/shogi/form.php');
exit();
?>

https://dalomo.net/shogi/

にアクセスすると

https://dalomo.net/shogi/form.php

に飛ぶ。

作成者の項目をDBから引っ張る

今は項目をベタ書きしてる。これだともし新たに作成者が追加された時に手動で対応しないとそのままになっちゃうなと思ったので、ここも動的に変更できるといいなと思った。で、作成者だけのテーブルを作ってdataテーブルの作成者の列から検索してなかったら追加とか考えたけど、Viewっていうのがあるみたいで、楽そうなのでそっちにする。

MariaDB [shogi]> create view makers as select distinct maker from data;
Query OK, 0 rows affected (0.003 sec)

MariaDB [shogi]> select * from makers;
+-----------------+
| maker           |
+-----------------+
| 内藤國雄        |
| 中村修          |
|                 |
| 藤井聡太        |
| 西村一義        |
略
| 村田智弘        |
| 服部慎一郎      |
+-----------------+
90 rows in set (0.014 sec)

できた。けど順番めちゃくちゃや。order by でソートできるらしい。もっかい

MariaDB [shogi]> create view makers as select distinct maker from data order by maker;
Query OK, 0 rows affected (0.001 sec)

MariaDB [shogi]> select * from makers;
+-----------------+
| maker           |
+-----------------+
|                 |
| 三枚堂達也      |
| 三浦弘行        |
| 上田初美        |
| 上野裕和        |
略
| 飯島栄治        |
| 黒田尭之        |
+-----------------+
90 rows in set (0.015 sec)

ならん。。。ていうか文字コード順なんですねこれ。いつもはエクセルさんに助けられていたわけか…!漢字の読み順にするには、じゃあどうすればいいんだろということで色々試してみる。

cast

MariaDB [shogi]> create view makers_cast as select distinct maker from data orde
r by cast(maker as char);
Query OK, 0 rows affected (0.002 sec)

MariaDB [shogi]> select * from makers_cast;
+-----------------+
| maker           |
+-----------------+
|                 |
| 三枚堂達也      |
| 三浦弘行        |
| 上田初美        |
| 上野裕和        |
略
| 飯島栄治        |
| 黒田尭之        |
+-----------------+
90 rows in set (0.013 sec)

変わらず…

collate

照合順序、というのがあるみたいで、なんか鬼門らしい。mariaDBでcollateに使える照合順序の一覧はどっかにないのかと探したらDB内で表示できるみたい。

ariaDB [shogi]> show collation like 'utf8mb4%';
+------------------------------+---------+------+---------+----------+---------+
| Collation                    | Charset | Id   | Default | Compiled | Sortlen |
+------------------------------+---------+------+---------+----------+---------+
| utf8mb4_general_ci           | utf8mb4 |   45 | Yes     | Yes      |       1 |
| utf8mb4_bin                  | utf8mb4 |   46 |         | Yes      |       1 |
| utf8mb4_unicode_ci           | utf8mb4 |  224 |         | Yes      |       8 |
| utf8mb4_icelandic_ci         | utf8mb4 |  225 |         | Yes      |       8 |
| utf8mb4_latvian_ci           | utf8mb4 |  226 |         | Yes      |       8 |
| utf8mb4_romanian_ci          | utf8mb4 |  227 |         | Yes      |       8 |
| utf8mb4_slovenian_ci         | utf8mb4 |  228 |         | Yes      |       8 |
| utf8mb4_polish_ci            | utf8mb4 |  229 |         | Yes      |       8 |
| utf8mb4_estonian_ci          | utf8mb4 |  230 |         | Yes      |       8 |
| utf8mb4_spanish_ci           | utf8mb4 |  231 |         | Yes      |       8 |
| utf8mb4_swedish_ci           | utf8mb4 |  232 |         | Yes      |       8 |
| utf8mb4_turkish_ci           | utf8mb4 |  233 |         | Yes      |       8 |
| utf8mb4_czech_ci             | utf8mb4 |  234 |         | Yes      |       8 |
| utf8mb4_danish_ci            | utf8mb4 |  235 |         | Yes      |       8 |
| utf8mb4_lithuanian_ci        | utf8mb4 |  236 |         | Yes      |       8 |
| utf8mb4_slovak_ci            | utf8mb4 |  237 |         | Yes      |       8 |
| utf8mb4_spanish2_ci          | utf8mb4 |  238 |         | Yes      |       8 |
| utf8mb4_roman_ci             | utf8mb4 |  239 |         | Yes      |       8 |
| utf8mb4_persian_ci           | utf8mb4 |  240 |         | Yes      |       8 |
| utf8mb4_esperanto_ci         | utf8mb4 |  241 |         | Yes      |       8 |
| utf8mb4_hungarian_ci         | utf8mb4 |  242 |         | Yes      |       8 |
| utf8mb4_sinhala_ci           | utf8mb4 |  243 |         | Yes      |       8 |
| utf8mb4_german2_ci           | utf8mb4 |  244 |         | Yes      |       8 |
| utf8mb4_croatian_mysql561_ci | utf8mb4 |  245 |         | Yes      |       8 |
| utf8mb4_unicode_520_ci       | utf8mb4 |  246 |         | Yes      |       8 |
| utf8mb4_vietnamese_ci        | utf8mb4 |  247 |         | Yes      |       8 |
| utf8mb4_croatian_ci          | utf8mb4 |  608 |         | Yes      |       8 |
| utf8mb4_myanmar_ci           | utf8mb4 |  609 |         | Yes      |       8 |
| utf8mb4_thai_520_w2          | utf8mb4 |  610 |         | Yes      |       4 |
| utf8mb4_general_nopad_ci     | utf8mb4 | 1069 |         | Yes      |       1 |
| utf8mb4_nopad_bin            | utf8mb4 | 1070 |         | Yes      |       1 |
| utf8mb4_unicode_nopad_ci     | utf8mb4 | 1248 |         | Yes      |       8 |
| utf8mb4_unicode_520_nopad_ci | utf8mb4 | 1270 |         | Yes      |       8 |
+------------------------------+---------+------+---------+----------+---------+
33 rows in set (0.001 sec)

utf8mb4_general_ci, utf8mb4_bin, utf8mb4_unicode_ciてのがよく使われるらし。

utf8mb4_bin

MariaDB [shogi]> create view makers_bin as select distinct maker from data order
 by maker collate utf8mb4_bin;
Query OK, 0 rows affected (0.003 sec)

MariaDB [shogi]> select * from makers_bin;
+-----------------+
| maker           |
+-----------------+
|                 |
| 三枚堂達也      |
| 三浦弘行        |
| 上田初美        |
| 上野裕和        |
略
| 飯島栄治        |
| 黒田尭之        |
+-----------------+
90 rows in set (0.014 sec)

む。

utf8mb4_general_ci

MariaDB [shogi]> create view makers_gen as select distinct maker from data order
 by maker collate utf8mb4_general_ci;
Query OK, 0 rows affected (0.004 sec)

MariaDB [shogi]> select * from makers_gen;
+-----------------+
| maker           |
+-----------------+
|                 |
| 三枚堂達也      |
| 三浦弘行        |
| 上田初美        |
| 上野裕和        |
略
| 飯島栄治        |
| 黒田尭之        |
+-----------------+
90 rows in set (0.013 sec)

むむ。

utf8mb4_unicode_ci

MariaDB [shogi]> create view makers_uni as select distinct maker from data order
 by maker collate utf8mb4_unicode_ci;
Query OK, 0 rows affected (0.002 sec)

MariaDB [shogi]> select * from makers_uni;
+-----------------+
| maker           |
+-----------------+
|                 |
| 三枚堂達也      |
| 三浦弘行        |
| 上田初美        |
| 上野裕和        |
略
| 飯島栄治        |
| 黒田尭之        |
+-----------------+
90 rows in set (0.014 sec)

むむむ。全部変わらない…。なんか間違ってんのかな。MySQLの方だと、utf8mb4_ja_0900_as_csとかutf8mb4_ja_0900_as_cs_ksもあるみたいなんだけど、MariaDBにはないから試せない…。

convert

convertで文字コードを変換できるらしい。日本語といえばShift-JISだな!今そう決めた!それに変換してしまえばいいのでは?と思い、将棋棋士の中に名前に絵文字使ったり、ダメ文字使ったりする親を持っていないことを祈りながらやってみる。

MariaDB [shogi]> create view makers_sjis as select distinct maker from data orde
r by convert(maker using sjis) collate sjis_japanese_ci;
Query OK, 0 rows affected (0.002 sec)

MariaDB [shogi]> select * from makers_sjis;
+-----------------+
| maker           |
+-----------------+
|                 |
| 阿部光瑠        |
| 安西勝一        |
| 安用寺孝功      |
| 伊藤果          |
略
| 有森浩三        |
| 脇謙二          |
+-----------------+
90 rows in set (0.013 sec)

おー変わった。音読み順になった。まぁぶっちゃけ振り仮名列を作ってそれをソートするってのが一番ちゃんとソートされるんだろうけど、結局メンテ必要になるだけなのでこれで十分かなー。でもーSJISに変換してるわけで、こっからPHPでDBからこれを引っ張って加工して表示するけど、HTMLのcharsetはutf8だし、てなると文字化けの匂いがプンプンする。UTF8のままであってくれ…!うーん、いきあたりばったりだけどこのまま進んでみて、またぶつかったら対策を考えよう。

コード書く

結果画面の時とほぼ一緒。

// makers
  $sql = "SELECT maker FROM makers_sjis";
  $state = $pdo->prepare($sql);
  $state->execute();
  $res = $state->fetchAll(PDO::FETCH_ASSOC);

  $optmaker = "";
  foreach ($res as $r) {
    $optmaker .= ''.$r["maker"].''."\n";
  }

変数の使い回しはホントはダメ。はい。結果なんかうまく表示されてる。viewとして作ったからSELECTで抽出時は元テーブルからデータ取得するとかなのかな(調べてない)。しかし項目数多いな…名前探すの大変。なんかいい方法ないかな?

とりあえずここまで!

カテゴリー: したい | タグ: , , , | コメントする

データベースを使ったサイトを作りたい⑧ PythonでMariaDBへデータ更新|更新編

MariaDB Connector/Python

ぶっちゃけ自分の用途だとINSERTしか使わないような気がするんですが、それでもいきなりやるのは怖いので前回作ったtestデータベースを使って練習したい。

練習

cursor.execute("CREATE TABLE mytest(id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,"
               "first_name VARCHAR(100), last_name VARCHAR(100), qdate DATE)")

cursor.execute("INSERT INTO mytest(first_name, last_name, qdate) VALUES (?,?,?)",
               ("山田", "太郎","2020-9-8"))

cursor.execute("SELECT id, first_name, last_name, qdate FROM mytest")

前回のBasic usageに日付追加して、日本語にしただけ。

$ python3 /home/dalomo/shogi/dbtest.py
Traceback (most recent call last):
  File "/home/dalomo/shogi/dbtest.py", line 13, in 
    cursor.execute("INSERT INTO mytest(first_name, last_name, qdate) VALUES (?,?,?)",
mariadb.OperationalError: Incorrect string value: '\xE5\xB1\xB1\xE7\x94\xB0' for column `test`.`mytest`.`first_name` at row 1

あれ?あーまた文字コード忘れた。一回データベース消して

create database test character set utf8mb4;

でもっかい作る。

$ python3 /home/dalomo/shogi/dbtest.py
1       山田    太郎    2020-09-08

おー、もういけんじゃね?他に

data = [
('山田', '太郎', '2020-9-8'),
('鈴木', '花子', '2020-9-8'),
('佐藤', '次郎', '2020-9-8')
]

cursor.executemany("INSERT INTO mytest(first_name, last_name, qdate) VALUES (?,?,?)", data)

cursor.execute("SELECT id, first_name, last_name, qdate FROM mytest")

row= cursor.fetchone()
print("---fetchone---")
print(*row, sep='\t')
pprint(row)
print(type(row))

cursor.execute("SELECT id, first_name, last_name, qdate FROM mytest")

row= cursor.fetchall()
print("---fetchall---")
print(*row, sep='\t')
pprint(row)
print(type(row))

cursor.execute("SELECT id, first_name, last_name, qdate FROM mytest")

row= cursor.fetchmany()
print("---fetchmany---")
print(*row, sep='\t')
pprint(row)
print(type(row))

てやると

$ python3 /home/dalomo/shogi/dbtest.py
---fetchone---
1       山田    太郎    2020-09-08
(1, '山田', '太郎', datetime.date(2020, 9, 8))
<class 'tuple'>
---fetchall---
(1, '山田', '太郎', datetime.date(2020, 9, 8))  (2, '鈴木', '花子', datetime.date(2020, 9, 8))  (3, '佐藤', '次郎', datetime.date(2020, 9, 8))
[(1, '山田', '太郎', datetime.date(2020, 9, 8)),
 (2, '鈴木', '花子', datetime.date(2020, 9, 8)),
 (3, '佐藤', '次郎', datetime.date(2020, 9, 8))]
<class 'list'>
---fetchmany---
(1, '山田', '太郎', datetime.date(2020, 9, 8))
[(1, '山田', '太郎', datetime.date(2020, 9, 8))]
<class 'list'>

こんなんとか。まぁSELECT使う予定ないけど。これはもういけるんじゃないか?書いてみよ。

本番

スクレイピングのコードの下に

conn= mariadb.connect(user="*", password="*", database="shogi", host="127.0.0.1")
cur= conn.cursor()

cur.execute("INSERT INTO data(date, title, maker, steps, url) VALUES (?,?,?,?,?)", 
            (q_date, title, maker, steps, url))

cur.close()
conn.close()

こんな感じで書いた、けど、エラーも出ずDBも更新されず何も起こらなかった…。エラーでないときの原因調査ってどうやるんだ。色々調べるとcommitが怪しいらしい!DBのオートコミット設定を調べてみると

MariaDB [(none)]> SELECT @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            1 |
+--------------+
1 row in set (0.000 sec)

あれー?なんで?ONになってるよね…。じゃあログを出してみようということで

https://mariadb.com/kb/en/general-query-log/

MariaDB [(none)]> SET GLOBAL general_log = 1;
Query OK, 0 rows affected (0.002 sec) MariaDB [(none)]> SET GLOBAL general_log_file='/var/log/mariadb/query.log'; Query OK, 0 rows affected (0.002 sec)

こう。クエリログを出力するようにしてみた。で、プログラム実行してみて、ログを見てみる。

200909 21:30:38	  5951 Connect	@localhost on shogi using TCP/IP
		  5951 Query	SET autocommit=0
		  5951 Prepare	INSERT INTO data(date, title, maker, steps, url) VALUES (?,?,?,?,?)
		  5951 Execute	INSERT INTO data(date, title, maker, steps, url) VALUES ('2020-09-09','2020年9月9日の詰将棋(杉本和陽作、9手詰)','杉本和陽','9','https://www.shogi.or.jp/tsume_shogi/everyday/2020999.html')
		  5951 Close stmt	
		  5951 Quit

おおおおっとー!autocommit=0やんけ!これかな?原因は。どういうこっちゃと思ってドキュメントよく読んで見ると

https://mariadb-corporation.github.io/mariadb-connector-python/module.html#mariadb.connect

New in version 1.0.1.

  • autocommit (bool or None): Specifies the autocommit settings: None will use the server default. True will enable autocommit, False will disable it (default).

うーん?だとするとBasic usageのヤツはいけてなんで俺のはいけないんだろ。もっかい調べてみて

MariaDB [(none)]> use test
MariaDB [test]> SELECT @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            1 |
+--------------+
1 row in set (0.000 sec)

MariaDB [test]> use shogi
MariaDB [shogi]> SELECT @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            1 |
+--------------+
1 row in set (0.000 sec)

んー?んー?分かんない!けどログだとオートコミットがオフになってるからオンになるように書いてみよう!

conn= mariadb.connect(
  user="*", 
  password="*", 
  database="shogi", 
  host="127.0.0.1", 
  autocommit=True
  )

DOKIDOKI

MariaDB [shogi]> select * from data where id between 1255 and 1300;
+------+------------+-------------------------------------------------------------+--------------+-------+-------------------------------------------------------------+
| id   | date       | title                                                       | maker        | steps | url                                                         |
+------+------------+-------------------------------------------------------------+--------------+-------+-------------------------------------------------------------+
| 1255 | 2020-09-06 | 2020年9月6日の詰将棋(中田章道作、11手詰)                  | 中田章道     |    11 | https://www.shogi.or.jp/tsume_shogi/everyday/20209611 |tml
| 1256 | 2020-09-07 | 2020年9月7日の詰将棋(3手詰)                               |              |     3 | https://www.shogi.or.jp/tsume_shogi/everyday/2020973.  |l
| 1269 | 2020-09-09 | 2020年9月9日の詰将棋(杉本和陽作、9手詰)                   | 杉本和陽     |     9 | https://www.shogi.or.jp/tsume_shogi/everyday/2020999.html   |
+------+------------+-------------------------------------------------------------+--------------+-------+-------------------------------------------------------------+
3 rows in set (0.001 sec)

いったーーーーーーーーーーーーー!!!!!!!!けどid飛びまくっとるし9/8分更新するの忘れてた!まぁいいや!いやっふ~!!

で、そのままcronで1日1回まわせばいっかーとか思ってたんだけど、それだとダブったり抜けたりする可能性はあるよなぁと思ったので、日付チェック入れることにする。でも

if row == t_date:
  print("日付一緒だよ")
  sys.exit()

って書いたけど、またもや何も起こらない。とりま

print(row)
print(t_date)
print(t_date.date)

したら

(datetime.date(2020, 9, 9),)
2020-09-09 00:00:00
<built-in method date of datetime.datetime object at 0x7f5babff0f90>

あれれー?なんだこれは、こんなつもりじゃないのに!

if row[0] == t_date.date():
  print("日付一緒だよ")
  sys.exit()

こうだと動いた。[]()忘れるよねー。多分これで事足りると思うんだけどな、どうだろう。ということで最終的にはこうなった

完成

import requests
from bs4 import BeautifulSoup
import mariadb
from datetime import datetime as dt
import sys

#scrape
target_url = 'https://www.shogi.or.jp/tsume_shogi/everyday/'
res = requests.get(target_url)
res.encoding = 'utf-8'

soup = BeautifulSoup(res.text, 'lxml')

contents = soup.find(id="contents")

url = contents.find('a').get('href')
title = contents.find('p').text
t_date = dt.strptime(title[0:title.find('日')].replace('年','-').replace('月','-'),'%Y-%m-%d')
q_date = t_date.date()
q_date = q_date.strftime('%Y-%m-%d')

maker = ''
steps = 0
if '、' in title:
  maker = title[title.find('(')+1:title.find('、')-1]
  steps = title[title.find('、')+1:title.find('手詰')]
else:
  steps = title[title.find('(')+1:title.find('手詰')]

#update
conn= mariadb.connect(
  user="*", 
  password="*", 
  database="shogi", 
  host="127.0.0.1", 
  autocommit=True
  )
cur= conn.cursor()

cur.execute("SELECT MAX(date) FROM data")
row = cur.fetchone()

if row[0] == t_date.date():
  cur.close()
  conn.close()
  sys.exit()

cur.execute("INSERT INTO data(date, title, maker, steps, url) VALUES (?,?,?,?,?)", 
            (q_date, title, maker, steps, url))

cur.close()
conn.close()

そういえば結局SELECT使ったな!あとはcronに登録しておいてちゃんと動いてるか確認しよ。

0 */3 * * * /usr/local/bin/python3 /home/dalomo/shogi/checkandupdate.py

こんな。3時間毎にチェックしにいく感じにした。さて結果どうなったかなとまずはMariaDBのログを見てみると

200910 12:00:02	  7465 Connect	@localhost on shogi using TCP/IP
		  7465 Query	SET autocommit=1
		  7465 Query	SELECT MAX(date) FROM data
		  7465 Prepare	INSERT INTO data(date, title, maker, steps, url) VALUES (?,?,?,?,?)
		  7465 Execute	INSERT INTO data(date, title, maker, steps, url) VALUES ('2020-09-10','2020年9月10日の詰将棋(3手詰)','','3','https://www.shogi.or.jp/tsume_shogi/everyday/20209103.html')
		  7465 Close stmt	
		  7465 Quit

おっ!おーっ!できてるかも!検索サイトで検索してみると

やったああああああああああ!!!!!!!!できてる!ちゃんと更新されてる!嬉しい~、いやー感激だわぁ~よかったー。次は、自動更新ができるようになったことで、ちょこちょこ改善できそうなところがあるので、それをやってこー。

カテゴリー: したい | タグ: , , | コメントする

データベースを使ったサイトを作りたい⑦ PythonでMariaDBへデータ更新|準備編

MariaDB Connector/Python

スクレイピングでPythonを使ったので、そのまま取得したデータをDBに更新したいなーと思った。探したらライブラリがあるみたい。なんか日本語の情報が少ない気がするけどなんでだろ。

https://mariadb.com/ja/resources/blog/how-to-connect-python-programs-to-mariadb/

https://pypi.org/project/mariadb/

https://mariadb-corporation.github.io/mariadb-connector-python/

準備

$ pip install mariadb

でインストール…エラー出た。

ERROR: Command errored out with exit status 1:
     command: /usr/local/bin/python3.8 -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-e_qwrg9i/mariadb/setup.py'"'"'; __file__='"'"'/tmp/pip-install-e_qwrg9i/mariadb/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-pe46t1ak
         cwd: /tmp/pip-install-e_qwrg9i/mariadb/
    Complete output (12 lines):
    /bin/sh: mariadb_config: command not found
    Traceback (most recent call last):
      File "", line 1, in 
      File "/tmp/pip-install-e_qwrg9i/mariadb/setup.py", line 26, in 
        cfg = get_config(options)
      File "/tmp/pip-install-e_qwrg9i/mariadb/mariadb_posix.py", line 51, in get_config
        cc_version = mariadb_config(config_prg, "cc_version")
      File "/tmp/pip-install-e_qwrg9i/mariadb/mariadb_posix.py", line 28, in mariadb_config
        raise EnvironmentError(
    OSError: mariadb_config not found.
    Please make sure, that MariaDB Connector/C is installed on your system, edit the configuration file 'site.cfg' and set the 'mariadb_config'
    option, which should point to the mariadb_config utility.
    ----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.

mariadb_configが無い?こっからいろいろ調べたけど何が効いたか分からん。

MariaDBをアップデート

https://mariadb.com/kb/en/upgrading-from-mariadb-55-to-mariadb-100/

https://qiita.com/egnr-in-6matroom/items/6dbb684ff03a228947bd

https://mariadb.com/kb/en/mariadb-package-repository-setup-and-usage/

$ curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash
[info] Repository file successfully written to /etc/yum.repos.d/mariadb.repo
[info] Adding trusted package signing keys...
[info] Successfully added trusted package signing keys

リポジトリを登録。

$ sudo systemctl stop mariadb
$ sudo yum update mariadb-server

止めてアプデ。

$ sudo yum remove MariaDB-server

なんかこれやってからの方がいいらしいがやってない。

$ sudo systemctl start mariadb

起動

$ mysql -u root -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 3
Server version: 10.5.5-MariaDB MariaDB Server

できたっぽい。5.5→10.5になった。

mariadb-connector-c

https://stackoverflow.com/questions/62584959/python-mariadb-pip-install-failed-missing-mariadb-config

https://github.com/mariadb-corporation/mariadb-connector-c/wiki/prerequisites

gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39)

gccバージョン確認

$ yum install cmake

cmakeインストール

yum install curl

curlインストール

ん?これってソースからビルドする感じ?やべぇ分からん。

https://stackoverflow.com/questions/51603067/installing-connector-c-for-mariadb

sudo yum install MariaDB-devel

こっち。でも色々やったけどerror: command ‘gcc’ failed with exit status 1ていうのが出て結局pip3 install mariadbでインストールできん。

同じページの

sudo yum -y install git gcc openssl-devel make cmake
git clone https://github.com/MariaDB/mariadb-connector-c.git
mkdir build && cd build
cmake ../mariadb-connector-c/ -DCMAKE_INSTALL_PREFIX=/usr
make
sudo make install

一行ずつやる。でもっかい

pip3 install mariadb
Collecting mariadb
  Using cached mariadb-1.0.1.tar.gz (65 kB)
Using legacy 'setup.py install' for mariadb, since package 'wheel' is not installed.
Installing collected packages: mariadb
    Running setup.py install for mariadb ... done
Successfully installed mariadb-1.0.1

いけた…?

試す

create database test;

でデータベースを作っとく。Basic usageにある

# Import MariaDB Connector/Python module
import mariadb

# Establish a connection
connection= mariadb.connect(user="myuser", database="test", host="localhost")

cursor= connection.cursor()

# Create a database table
cursor.execute("DROP TABLE IF EXISTS mytest")
cursor.execute("CREATE TABLE mytest(id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,"
               "first_name VARCHAR(100), last_name VARCHAR(100))")


# Populate table with some data
cursor.execute("INSERT INTO mytest(first_name, last_name) VALUES (?,?)",
               ("Robert", "Redford"))

# retrieve data
cursor.execute("SELECT id, first_name, last_name FROM mytest")

# print content
row= cursor.fetchone()
print(*row, sep='\t')

# free resources
cursor.close()
connection.close()

だけど、

#ここに
connection= mariadb.connect(user="myuser", database="test", host="localhost") #パスワード入れた connection= mariadb.connect(user="myuser",password="password", database="test", host="localhost")

じゃー実行

python3 dbtest.py
Traceback (most recent call last):
  File "dbtest.py", line 2, in 
    import mariadb
  File "/usr/local/lib/python3.8/site-packages/mariadb/__init__.py", line 7, in 
    from ._mariadb import (
ImportError: libmariadb.so.3: cannot open shared object file: No such file or directory

またエラーかよおおおお…。疲れてきちゃった…。どうやらパスが通ってないために起きるエラーらしい。

ImportError: libmariadb.so.3: cannot open shared object file: No such file or directory

$ sudo find / -name libmariadb.so.3
/root/build/libmariadb/libmariadb.so.3
/usr/lib/mariadb/libmariadb.so.3

探すと見つかる。

$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/mariadb

こう。でもっかい

$ python3 /home/dalomo/shogi/dbtest.py

結果

Traceback (most recent call last):
  File "/home/dalomo/shogi/dbtest.py", line 5, in 
    connection= mariadb.connect(user="",password="", database="test", host="localhost")
mariadb.OperationalError: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

ちょっと進んだ!けど、またエラーだ…。これはちょっと置いといて、さっきのパスの通し方は一時的なものらしい。ので永続的に設定する。

https://qiita.com/Esfahan/items/0064d845ca6faf7f3d47

ここ見ながら

$ ldconfig -p | grep maria
        libmariadbd.so.19 (libc6,x86-64) => /lib64/libmariadbd.so.19
        libmariadbd.so (libc6,x86-64) => /lib64/libmariadbd.so

確認してみたけど無い。そしたら

$ vi /etc/ld.so.conf.d/mariadb-3.1.9.conf

/usr/lib/mariadb

を新規に書いて保存。

$ ldconfig

更新して確認してみる。

$ ldconfig -p | grep maria
        libmariadbd.so.19 (libc6,x86-64) => /lib64/libmariadbd.so.19
        libmariadbd.so (libc6,x86-64) => /lib64/libmariadbd.so
        libmariadb.so.3 (libc6,x86-64) => /usr/lib/mariadb/libmariadb.so.3
        libmariadb.so (libc6,x86-64) => /usr/lib/mariadb/libmariadb.so

よさげ。

mariadb.OperationalError: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

そしたらこのエラーをどうにかしたい。

mariadb.OperationalError: Can’t connect to local MySQL server through socket ‘/tmp/mysql.sock’ (2)

なんか

http://www.hi-ho.ne.jp/tsumiki/book_sup2.html

ソケットが無い。もしくはpythonが使おうとしてるソケットとDBが使ってるソケットが一致してない。みたいな。MariaDBが使ってるソケットを調べる。

$ mariadb_config --socket
/tmp/mysql.sock

えー、そうなの?んーDBが使ってるソケットを変更するのはなんか怖いな。ちょっと調べると

https://stackoverflow.com/questions/16325607/cant-connect-to-local-mysql-server-through-socket-tmp-mysql-sock

ここに

  • If host is set to localhost, then a socket or pipe is used.
  • If host is set to 127.0.0.1, then the client is forced to use TCP/IP.

 

  • ホストが localhost に設定されている場合は、ソケットまたはパイプが使用されます。
  • ホストが 127.0.0.0.1 に設定されている場合、クライアントは強制的に TCP/IP を使用します。

ほーほう。もしかしたら

connection= mariadb.connect(user="", password="", database="test", host="127.0.0.1")

こうしてみると?

$ python3 /home/dalomo/shogi/dbtest.py
1       Robert  Redford

おおおおおおおおおおおおおおおおお!!!!!!!!!!!!!!!!!!!!!!!!!!!

できた!!!!!!!!!!!!!!!!!!!!!!!!!!!

あーでも、ソケット使うのとTCP/IP使うのとどっちがどう違うんだろ。ソケット使うほうがサーバー内から直で行ってる感があって、TCP/IPだとネットワーク経由してそうなイメージ(分かってない)。やっぱソケット経由で行ける方法を採用したほうがいいんかな…。でもな…せっかく動いたしな…

いっか。まぁ後学のために、/tmp/mysql.sockを作って所有権を変更したり、/etc/my.cnfを編集して使用するソケットを変えたりとか、なんか色々あるみたいよ。

なんか疲れたし使えるようになったのは分かったからまた今度にしよう。

カテゴリー: したい | タグ: , , | コメントする

データベースを使ったサイトを作りたい⑥ Python+BeautifulSoupで最新データをスクレイピング

スクレイピング

元々はVBA+IEでスクレイピングをしてデータを収集してデータベースを作った。でもそれを毎回やるのはめんどいので自動化できると良い。サーバー上でスクレイピングするやり方って何があるんだろうと探してみたらPythonのライブラリでBeautifulSoupというものを見つけた。これで定期的に更新されてるか見に行きつつスクレイピングして必要なデータを抽出して、なおかつデータベースを更新できればいいな。とりあえずスクレイピングしよー。

Beautiful Soupでスクレイピング

https://www.crummy.com/software/BeautifulSoup/bs4/doc/

公式ドキュメント。今は4.9.0が最新?

http://kondou.com/BS4/

こっちは日本語訳。これは4.2.0が基みたい。まぁやってこー。

インストール

CentOSなので

$ pip install beautifulsoup4
Collecting beautifulsoup4
Downloading beautifulsoup4-4.9.1-py3-none-any.whl (115 kB)
|????????????????????????????????| 115 kB 17.9 MB/s
Collecting soupsieve>1.2
Downloading soupsieve-2.0.1-py3-none-any.whl (32 kB)
Installing collected packages: soupsieve, beautifulsoup4
Successfully installed beautifulsoup4-4.9.1 soupsieve-2.0.1

された。

HTMLパーサーのインストール

HTMLを解析してくれるやつ。Pythonで標準に入ってるらしいやつとなんか色々。そのうちlxmlのHTMLパーサーを使おうと思う。速いらしいよ。

$ pip install lxml
Collecting lxml
  Downloading lxml-4.5.2-cp38-cp38-manylinux1_x86_64.whl (5.4 MB)
     |????????????????????????????????| 5.4 MB 10.6 MB/s
Installing collected packages: lxml
Successfully installed lxml-4.5.2

Requestsのインストール

https://requests.readthedocs.io/en/master/

HTMLをそのまま取得する時に使うやつみたい。Pythonの標準にもUrllibというライブラリが入ってるらしいけど、こっちのほうが使いやすいらしい。らしいばっかだ。ただ自分の目的だと外部公開されてる固定ページに行って取得するだけだし別にそこまでするようなものでもないかもしんない。まぁ一応入れとく!

$ pip install requests
Collecting requests
  Downloading requests-2.24.0-py2.py3-none-any.whl (61 kB)
     |????????????????????????????????| 61 kB 727 kB/s
Collecting chardet<4,>=3.0.2
  Downloading chardet-3.0.4-py2.py3-none-any.whl (133 kB)
     |????????????????????????????????| 133 kB 22.3 MB/s
Collecting certifi>=2017.4.17
  Downloading certifi-2020.6.20-py2.py3-none-any.whl (156 kB)
     |????????????????????????????????| 156 kB 30.5 MB/s
Collecting urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1
  Downloading urllib3-1.25.10-py2.py3-none-any.whl (127 kB)
     |????????????????????????????????| 127 kB 17.0 MB/s
Collecting idna<3,>=2.5
  Downloading idna-2.10-py2.py3-none-any.whl (58 kB)
     |????????????????????????????????| 58 kB 6.0 MB/s
Installing collected packages: chardet, certifi, urllib3, idna, requests
Successfully installed certifi-2020.6.20 chardet-3.0.4 idna-2.10 requests-2.24.0 urllib3-1.25.10

できた。

使ってみる

まずちゃんと取得できるか試す。コード書いた。

import requests
from bs4 import BeautifulSoup

url = 'https://www.shogi.or.jp/tsume_shogi/everyday/'
res = requests.get(url)

soup = BeautifulSoup(res.text, 'lxml')
print(soup.title)

結果

python3 scrape.py
<title>a??a??a?≪a?!ec°a°?a£?i??ec°a°?a£?a?≫a¬!a?Ra,€a??i??a?\a?¬a°?a£?e€£c??</title>

おっとー、また文字化けかい…。んーと

print('こんにちわ')

$ python3 hello.py
こんにちわ

表示される。

import requests

url = 'https://www.shogi.or.jp/tsume_shogi/everyday/'
res = requests.get(url)

print(res.text)

こうして、結果

<title>a??a??a?≪a?!ec°a°?a£?i??ec°a°?a£?a?≫a¬!a?Ra,€a??i??a?\a?¬a°?a£?e€£c??</title>

あーこの時点でもう化けてる。”Requests 文字化け”とかで検索

https://qiita.com/nittyan/items/d3f49a7699296a58605b

とか。自分でも試してみる。

print(res.encoding)

に変えて

$ python3 scrape.py
ISO-8859-1

おー。qiitaだとapparent_encodingを使ってるけどすでにサイト側の文字コードがutf-8だと分かってるので

import requests
from bs4 import BeautifulSoup

url = 'https://www.shogi.or.jp/tsume_shogi/everyday/'
res = requests.get(url)
res.encoding = 'utf-8'

soup = BeautifulSoup(res.text, 'lxml')
print(soup.title)

簡易に文字コードを強制的に指定してあげる。結果

$ python3 scrape.py
<title>まいにち詰将棋|詰将棋・次の一手|日本将棋連盟</title>

取得できた!そしたら最新出題日のデータを取得してみる。

最新を取得

CSSセレクタで指定するのはいまいちよく分かってないのでfindとfind_all使ってやってく。ソース見ると、id=”contents“の中のli要素1個目で、aとpの要素を取得できれば良さげ。その後p要素のテキストを加工すればデータ作れそう。で、こんな感じになった。

import requests
from bs4 import BeautifulSoup

target_url = 'https://www.shogi.or.jp/tsume_shogi/everyday/'
res = requests.get(target_url)
res.encoding = 'utf-8'

soup = BeautifulSoup(res.text, 'lxml')

contents = soup.find(id="contents")
url = contents.find('a').get('href')

print(url)

title = contents.find('p').text

print(title)

q_date = title[0:title.find('日')].replace('年','-').replace('月','-')

print(q_date)

maker = ''
steps = 0
if '、' in title:
  maker = title[title.find('(')+1:title.find('、')-1]
  steps = title[title.find('、')+1:title.find('手詰')]
else:
  steps = title[title.find('(')+1:title.find('手詰')]

print(maker)
print(steps)

結果

$ python3 scrape.py
https://www.shogi.or.jp/tsume_shogi/everyday/2020959.html
2020年9月5日の詰将棋(服部慎一郎作、9手詰)
2020-9-5
服部慎一郎
9

とりあえず9/5分しかチェックしてないけど大丈夫かな~。BFのfindの引数の書き方がよく分かんなかったので何回もfindした。liはいらんかったね。データの切り出しも正規表現とか使えるともっといい感じに書けるんだろうなぁ…。まだまだですね。まぁ目的のデータはゲットできそうなので、次はこれをDBに更新していく処理を書こう!

カテゴリー: したい | タグ: , , , , | コメントする

データベースを使ったサイトを作りたい⑤ フォームと結果画面

フォームと結果の画面

フォームと検索画面を作りたい。多分この2つさえあれば体裁は整うはず。もうちょっと詰めてみる。

こんな感じになるといいな

絵を描く。

フォーム画面

検索条件を指定する画面。日付は始まりが2017年4月1日なのでそれより前の日付入れられないようにしたい。全期間を検索できるようにして負荷とか大丈夫なのかな。経験がないからよく分かんない。製作者はDBに入ってる製作者をまとめて、ドロップダウンで指定できるようにしたい…けどとりあえずは手作業で製作者のリスト作って選択できるようにしたい。ゆくゆくはここも自動でリストを作成できるようになればいいな。手数は見た感じ3,5,7,11手詰めしかなさ気なのでそれだけ選択できればいいかな。製作者と手数は空白もあり得るからそれにも対応したい。。。日付は必須のほうがいいのかな…?んー、理想は何も指定がない時は検索できないようにして、なにかしらの指定があったらそれに合わせるみたいなのがいいんだけど、そこまでできるかちょっと微妙なので、できれば、やれたら、おいおい、かな。

結果画面

ほんとは、フォーム画面の下に結果を表示させて、一画面で完結する方が格好良いかなぁって思うんだけどそこまで自分にできるかは分からない、ていうか想像ができない。だからPHPのチュートリアルでやったみたいな、ボタンを押したら違うphpファイルを呼び出して、そっちで表示する、みたいなのが、一回やってるし想像しやすかったのでそんな感じにしたい、したいっていうかこれならできそうっていうか。検索結果の件数を表示して、その下に結果をテーブルで表示できればいいかなぁ。もっと言うとテーブルヘッダをクリックすると昇順・降順にソートしてくれるみたいな機能もほしい。でもそこまではまだ望まない。ていうかやり方分からんちんだし。まずは基本というか、最低限の基礎になるものを作ってみたい。

フォーム画面

なんかHTMLタグ含むコードがうまく貼れない。いいや。

https://dalomo.net/shogi/form.php

こんな感じになった。一発result.phpを作って、POSTデータを受けてみる。

<?php
echo $_POST['date-from'];
echo $_POST['date-to'];
echo $_POST['maker'];
echo $_POST['steps'];
?>

結果。

いいのでは。じゃあresult.phpの方を作っていく。

結果画面

やっぱしなんかHTMLのタグを含むコードが上手く貼れないのでPHPの部分だけ。

<?php
require ('config.php');

  try {
    $pdo = new PDO($dsn, $user, $password);
  } catch (PDOException $ext) {
  }

  $countsql = <<< EOD
              SELECT COUNT(*) FROM data
              WHERE date BETWEEN :date_from AND :date_to  
  EOD;

$df = htmlspecialchars($_POST['date-from'], ENT_QUOTES|ENT_HTML5, "UTF-8");
$dt = htmlspecialchars($_POST['date-to'], ENT_QUOTES|ENT_HTML5, "UTF-8");
$maker = htmlspecialchars($_POST['maker'], ENT_QUOTES|ENT_HTML5, "UTF-8");
$steps = htmlspecialchars($_POST['steps'], ENT_QUOTES|ENT_HTML5, "UTF-8");

if($maker <> ""){
  $countsql .= " AND maker = :maker";
}

if($steps <> ""){
  $countsql .= " AND steps = :steps";
}

$state = $pdo->prepare($countsql);
$state->bindValue(':date_from',$df);
$state->bindValue(':date_to',$dt);

if($maker <> ""){
  $state->bindValue(':maker',$maker);
}

if($steps <> ""){
  $state->bindValue(':steps',$steps);
}

$state->execute();
$res = $state->fetchAll(PDO::FETCH_ASSOC);

$num = $res[0]["COUNT(*)"];

$sql = str_replace("COUNT(*)","*",$countsql);

$state = $pdo->prepare($sql);
$state->bindValue(':date_from',$df);
$state->bindValue(':date_to',$dt);

if($maker <> ""){
  $state->bindValue(':maker',$maker);
}

if($steps <> ""){
  $state->bindValue(':steps',$steps);
}

$state->execute();
$res = $state->fetchAll(PDO::FETCH_ASSOC);

$pdo = null;
?>
<?php
$restbl = "";
      
      foreach ($res as $r) {
        $restbl .= "";
        $restbl .= "".$r["date"]."";
        $restbl .= "".$r["maker"]."";
        $restbl .= "".$r["steps"]."";
        $restbl .= "'.$r["url"]."";
        $restbl .= "";
      }

      $restbl .= "";

      echo $restbl
?>

えっと、まー汚いコードだ…。同じような処理繰り返してるし、良くはないと思う。。。まぁそれでも初めて形にしたのだし頑張ったからいいよね。フォームからのPOSTで送られたデータをhtmlspecialcharsで受けて、入力内容によってSQL文の組み立てを変えて、COUNTで件数取って、結果も取って、それを基に<table>の内容を作ってく。

ちゃんと表示されてるよ~!!すごい嬉しい、やっとなんかちゃんと形になった。とりあえず基本の形はできたよ!次はデータの自動更新をやりたいなぁ。

https://dalomo.net/shogi/form.php

カテゴリー: したい | タグ: , , , | コメントする

データベースを使ったサイトを作りたい④ PHPのPDOでDBに接続する

PHP Data Object

DBからデータ引っ張り出せればあとはなんとかなるんじゃなかろうかという期待の元、とにかくまずはPHPでデータベース操作するやり方を調べる。そのうちPDOっていうやつを見つけた。やってみましょう。

DBに接続する

接続情報は別にサーバー外から見れるわけではないっぽいんだけど、なんかこうぃので外部ファイルに移しとく。

<?php
  $dsn = 'dsn:host=localhost;dbname=shogi';
  $user = '****';
  $password = '******';
?>

でshogi_config.phpに保存。そんでメインの方でrequireで引っ張る。で、色々書いて

<?php
  require ('shogi_config.php');

  try {
    $pdo = new PDO($dsn, $user, $password);
    print ('接続しました。');
  } catch (PDOException $ext) {
    die('接続してない。'.$ext->getMessage());
  }

  $pdo = null;
?>

うむ。最初requireの後に;入れるの忘れてて、syntax error, unexpected ‘try’ (T_TRY)っていうエラーが出ておった。まぁそれはそれとして。この状態でサーバーにアップしてみたら、接続しました。って表示された。幸先がよろしい。

SQLを発行する

とりま変数とか使わずにべた書きする。

  $sql = "SELECT * FROM data WHERE id=1234";

  $state = $pdo->query($sql);
  $res = $state->fetch(PDO::FETCH_NUM);
  foreach ($res as $r => $v) {
    print($v."\n");  
  }

て書く。query投げて戻り値をfetchしてprint。

結果

文字化けしとるなー。また文字コードがどうたらかな。config.phpの$dsnに

charset=utf8

を追加したら直った!じゃあレコードが複数ある場合はどうすんの?と試してみる。sqlを

$sql = "SELECT * FROM data WHERE id IN (1234, 1235)";

てしてみたけど、1234の方しか表示されない。で、色々試してみたら

$sql = "SELECT * FROM data WHERE id IN (1234, 1235)";

  $state = $pdo->query($sql);
  $res = $state->fetch(PDO::FETCH_ASSOC);
  foreach ($res as $r => $v) {
    print($v."\n<br>");  
  }
  
  $res = $state->fetch(PDO::FETCH_ASSOC);
  foreach ($res as $r => $v) {
    print($v."\n<br>");  
  }

っつって、fetchを2回やってみたらどっちも表示された。

うーん、なんかあんまコードがキレイじゃないね。どうやるのがいいんだろうなぁ。まぁそれは置いといて、変数使うやつやる。

プレースホルダー

外部入力をまんまSQL文につないで発行したりすると、悪意を持った攻撃者に悪いことされる。SQLインジェクションってやつだ!基本情報で出てきたなぁ。でそれを防ぐためにプレースホルダーを使いましょう、ということみたい。SQL文のテンプレートを作っておいて、プリペアードステートメントを介して値を設定するみたいな流れらしい。この前作ったDBを検索したいってなると、日付、作成者、手数で絞るような使い方になるのかなーって思う。それ用にSQLのテンプレートを作れるだろか。

$sql = <<<EOD
          SELECT * FROM data 
          WHERE date BETWEEN :date_from AND :date_to
          AND maker = :maker
          AND steps = :steps
EOD;

  $df = '2020-08-01';
  $dt = '2020-08-15';
  $maker = '';
  $steps = 3;

  $state = $pdo->prepare($sql);
  $state->bindValue(':date_from',$df);
  $state->bindValue(':date_to',$dt);
  $state->bindValue(':maker',$maker);
  $state->bindValue(':steps',$steps);

  $state->execute();
  $res = $state->fetchAll(PDO::FETCH_ASSOC);

  var_dump($res);

こんな感じかな…。これ例えばmakerはワイルドカードでいい、みたいな時ってどうすればいいんだろうな~。

実行するとこんな。ちゃんと取得できてるっぽい。そしたら、んー、フォームを作ってみようかな?

カテゴリー: したい | タグ: , , | コメントする

データベースを使ったサイトを作りたい③ PHPの簡易チュートリアル

サーバーサイド言語

サーバーサイド言語って何があるんだろうなーって、存在を知ってるのはPHPとRubyとPerlとJava Servletとか…?これが合ってるのかすら分からん。なんにしようかなーって思ったんだけどPHPでいってみることにする。初心者でもできる!とか適当に書いても動く!とか言われてるみたいなので自分でもできるんじゃないかなぁって思ったから。

準備

どういう感じで動くんだろうと調べてみたら、HTML内に書いて、Apacheが入ってるサーバー上に.phpって拡張子で保存して、クライアントがリクエストするとphpが実行されてサーバー側で処理されて、phpのソースは省いた状態でレスポンス返す、みたいな。へー。じゃあ別にテキストファイルにコード書いてアップすりゃそれでいいんだなぁって思ったけど、なんかツラそうな気がしたのでVSCを使う。他のエディタ使いたい場合こことかから探すといいらし。

Cannot validate since no PHP executable is set. Use the setting ‘php.validate.executablePath’ to configure the PHP executable.

シンタックスハイライトは効いてる気がするんだけど、このエラーメッセージが出たのでとりあえずphpを落としてくる。

https://www.php.net/downloads

のWindowsから、x64のスレッドセーフのやつにした。違いは理解していません。適当な場所に解凍してsetting.jsonにパスを指定すればいいみたい。

"php.validate.executablePath": "**\\php.exe"

みたいな。パス区切り文字はエスケープしないとダメだってさ。

PHP IntelliSense

コード補完的なものは無いかなー?と探してみたら

https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-intellisense

があった。使おうと思ったんだけどレビュー見たらめっちゃ叩かれてるし、更新も止まってるみたい。一応使ってみたら自分だとLoading…でずっと止まったままとかになる。なので違うのにする。

PHP Intelephense

っていうのがあるみたい。

https://marketplace.visualstudio.com/items?itemName=bmewburn.vscode-intelephense-client

https://intelephense.com/

プレミアム購入してねアナウンスが出るらしいけど、概ね好評っぽいのでこっち使ってみる。

クイックスタート

  1. Extensionsを開く。
  2. @builtin phpで検索
  3. PHP Language Featuresを無効化する。PHP Language Basicsはそのまま。(シンタックスハイライトのために)
  4. settingsのfiles.associationsにitem “*.module” value “php”を追加。

なんのためにやるのかは分かってないけど、やってねってことなのでやってみた。

…で使ってみたんだけど、うーん、どうなんだろう。どうなんですか?ぶっちゃけ初心者すぎてどう違くなったのかよく分かんない。。。いいかな、どっちも入れなくても…。どうせ使いこなせないだろうし…。ということでどっちも消した。

Hello World

https://www.php.net/manual/ja/tutorial.php

ここに載ってたhello.phpを作ってサーバーにアップしてみた。

https://dalomo.net/shogi/hello.php

おー、ちゃんと表示されてる~。ソース見てもPHPのソースは残ってない。すごいなぁ。この後

phpinfo();

もやってみて、ちゃんと表示されてた!いえーい。あとチュートリアルに載ってたフォームも作ってみた。コピペだけど。

https://dalomo.net/shogi/info.php

ちゃんと動くね。すごいや。

カテゴリー: したい | タグ: , | コメントする

データベースを使ったサイトを作りたい② データをDBに格納する

データベースにデータを追加

この前作ったcsvからデータをデータベースにぶっこんでいきたい。どうやるんだろうなーとプログラム書いて一行ずつインサートとかかなと思ったら、ググったところcsvから読み込むコマンドがあるらしい。丁度いいのでそれを使おう。ブログ作った時にデータベースも作ってあるはずなので、それに新規テーブルを作ればいいはず。使ってるのはMariaDBだけどMySQLの構文でイケるみたい。まぁどっちも知らんのだけど。

データベースのパスワード忘れた

やべぇ、どうしよう。色々探したら、ワードプレスのwp-config.phpに書いてあるらしい。開いてみたらそのものずばり書いてあったので事なきを得た。あぶねー。

とりあえず試す

まずは慣れようと思ったので、試しにテストテーブル作ってみる。

mysql -u root -p

で、パスワード聞かれるのでログイン。

show databases;

で今のデータベースを見てみる。

+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| wordpressdb        |
+--------------------+
4 rows in set (0.00 sec)

おー、でた。すごーい、プログラマーみたい。じゃあ、

create database test;
Query OK, 1 row affected (0.00 sec)

作れたっぽい。もっかいshow

+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
| wordpressdb        |
+--------------------+
5 rows in set (0.00 sec)

いやっふ~。

use test;
Database changed

testに接続。なんかテーブル作ろ。んー

create table list (no int, name text);
Query OK, 0 rows affected (0.31 sec)

できたかな?確認は

show tables;
+----------------+
| Tables_in_test |
+----------------+
| list           |
+----------------+
1 row in set (0.00 sec)

いーねー。じゃ基本らしい4つを

INSERT 挿入

MariaDB [test]> insert into list (no, name) values (1, 'yamada');
Query OK, 1 row affected (0.00 sec)

MariaDB [test]> insert into list (no, name) values (2, 'suzuki');
Query OK, 1 row affected (0.00 sec)

MariaDB [test]> insert into list (no, name) values (3, 'tanaka');
Query OK, 1 row affected (0.00 sec)

MariaDB [test]> insert into list (no, name) values (4, '遠藤');
Query OK, 1 row affected, 1 warning (0.00 sec)

MariaDB [test]> insert into list (no, name) values (5, '松本');
Query OK, 1 row affected, 1 warning (0.00 sec)

上3つはいい感じ、下はなんかwarningってなってるね。これを見るにはー?

show warnings;

で、見れるみたい。でも直前のだけだって。じゃもっかいinsertして直後にやってみると

MariaDB [test]> insert into list (no, name) values (6, '浜田');
Query OK, 1 row affected, 1 warning (0.00 sec)

MariaDB [test]> show warnings;
+---------+------+-------------------------------------------------------------------------------+
| Level   | Code | Message                                                                       |
+---------+------+-------------------------------------------------------------------------------+
| Warning | 1366 | Incorrect string value: '\xE6\xB5\x9C\xE7\x94\xB0' for column 'name' at row 1 |
+---------+------+-------------------------------------------------------------------------------+
1 row in set (0.00 sec)

ほーん?なんか文字コードの問題らしい。

MariaDB [test]> show variables like "chara%";
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | latin1                     |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

これを、utf8mb4に変えればいいみたい。みたい。でもさ、今の今までブログでデータベースは自動で使ってきたようなもんじゃん。これ変えちゃって他に影響とかでないのかなぁ?見た感じでしかないけど他のデータベースと共用の設定じゃないのかなこれ。確認してみよう。

MariaDB [test]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
| wordpressdb        |
+--------------------+
5 rows in set (0.00 sec)

MariaDB [test]> use wordpressdb;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

MariaDB [wordpressdb]> show variables like "chara%";
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8mb4                    |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

あー、character_set_databaseのとこが違うね。てことはデータベースごとに違う設定になってるんか。じゃtestデータベースもcharacter_set_databaseのとこだけ変えれればそれでいいのかな?どうやるのかなっと

https://hodalog.com/modify-the-character-encode-of-mysql/

こちらを参考にして既存のやつを換えるコマンドを叩く。

MariaDB [test]> ALTER DATABASE test CHARACTER SET utf8mb4 COLLATE utf8mb4_genera
l_ci;
Query OK, 1 row affected (0.00 sec)

MariaDB [test]> ALTER TABLE list CONVERT TO character SET utf8mb4 COLLATE utf8mb
4_unicode_ci;
Query OK, 6 rows affected (0.04 sec)
Records: 6  Duplicates: 0  Warnings: 0

MariaDB [test]> ALTER TABLE list CHANGE name name TEXT CHARACTER SET utf8mb4 COL
LATE utf8mb4_unicode_ci;
Query OK, 6 rows affected (0.01 sec)
Records: 6  Duplicates: 0  Warnings: 0

どーだろ、ダイジョブかな。もっかいINSERTする。

MariaDB [test]> insert into list (no, name) values (7, '斎藤');
Query OK, 1 row affected (0.01 sec)

おっけーそう!

SELECT 選択

とりあえず全部

MariaDB [test]> select * from list;
+------+--------+
| no   | name   |
+------+--------+
|    1 | yamada |
|    2 | suzuki |
|    3 | tanaka |
|    4 | ??     |
|    5 | ??     |
|    6 | ??     |
|    7 | 斎藤   |
+------+--------+
7 rows in set (0.01 sec)

あれれー…4, 5, 6が?になっちゃったか。んー、スルーしよう。とにかく文字コードが悪かったんだな。次から気をつける。にしてもどうやるのがいいんだろうなぁ。SELECTは練習するにしてもいっぱいあるのでこれだけでいいや。

UPDATE 更新

MariaDB [test]> update list set name="遠藤" where no=4;
Query OK, 1 row affected (0.10 sec)
Rows matched: 1  Changed: 1  Warnings: 0

MariaDB [test]> update list set name="松本" where no=5;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

MariaDB [test]> update list set name="浜田" where no=6;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

MariaDB [test]> select * from list;
+------+--------+
| no   | name   |
+------+--------+
|    1 | yamada |
|    2 | suzuki |
|    3 | tanaka |
|    4 | 遠藤   |
|    5 | 松本   |
|    6 | 浜田   |
|    7 | 斎藤   |
+------+--------+
7 rows in set (0.00 sec)

できたー。

DELETE 削除

MariaDB [test]> delete from list where no=2;
Query OK, 1 row affected (0.01 sec)

MariaDB [test]> delete from list where no=4;
Query OK, 1 row affected (0.00 sec)

MariaDB [test]> delete from list where no=6;
Query OK, 1 row affected (0.00 sec)

MariaDB [test]> delete from list where no=8;
Query OK, 0 rows affected (0.00 sec)

MariaDB [test]> select * from list;
+------+--------+
| no   | name   |
+------+--------+
|    1 | yamada |
|    3 | tanaka |
|    5 | 松本   |
|    7 | 斎藤   |
+------+--------+
4 rows in set (0.00 sec)

おっけーですね。とりあえず触り方はなんとなく分かったので削除しましょ。

MariaDB [test]> drop database test;
Query OK, 1 row affected (0.01 sec)

MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| wordpressdb        |
+--------------------+
4 rows in set (0.00 sec)

消えた。じゃーいよいよ本番のやつ作ろう。

本番のやつ作る

database

MariaDB [(none)]> create database shogi character set utf8mb4;
Query OK, 1 row affected (0.00 sec)

character set **で、文字コードを設定できることを知ったので、やっておいてみる。

table

MariaDB [shogi]> create table data ( id int not null auto_increment, date date,
 title text, maker text, steps int, url text, primary key (id));
Query OK, 0 rows affected (0.00 sec)

一意の値ってなると、日付はそうっぽいんだけど、日付を主キーに設定するのってどうなのかよく分かんないからidカラムを作ってオートインクリメントにしてみた。dateカラムは型名と一緒じゃん!って思ったけど、やってみたら通ったのでいいみたい。title, maker, urlは脳死でTEXT型にした。なんかVARCHARでちゃんと指定したほうが、パフォーマンスいいみたいだけど、まぁいいやの精神。stepsは一応INT型にした。別に計算するつもりもないのだけれど。date, title, steps, urlにはnot nullつけるべきなのかもしれない。

LOAD DATA INFILE

作成したcsvファイルを適当な場所において、LOAD DATA INFILE構文を使用してテーブルに読み込めるそう。とりあえずやってみる。

MariaDB [shogi]> load data local infile "shogi.csv" into table data fields terminated by ',';
Query OK, 5 rows affected, 6215 warnings (0.02 sec)
Records: 1244 Deleted: 0 Skipped: 1239 Warnings: 6215

よっこいしょー!わぁっ!Warningsが出ちゃった…。とりあえずWarnings見よう…

MariaDB [shogi]> show warnings;
+---------+------+---------------------------------------------------------------------------------------------------------------------+
| Level   | Code | Message                                                                                                             |
+---------+------+---------------------------------------------------------------------------------------------------------------------+
| Warning | 1366 | Incorrect integer value: 'date' for column 'id' at row 1                                                            |
| Warning | 1265 | Data truncated for column 'date' at row 1                                                                           |
' for column 'steps' at row 1                                                         |
| Warning | 1261 | Row 1 doesn't contain data for all columns                                                                          |
| Warning | 1265 | Data truncated for column 'id' at row 2                                                                             |
| Warning | 1265 | Data truncated for column 'date' at row 2                                                                           |
| Warning | 1366 | Incorrect integer value: 'https://www.shogi.or.jp/tsume_shogi' for column 'steps' at row 2    |
| Warning | 1261 | Row 2 doesn't contain data for all columns                                                                          |
| Warning | 1062 | Duplicate entry '2017' for key 'PRIMARY'                                                                            |
| Warning | 1265 | Data truncated for column 'id' at row 3                                                                             |
| Warning | 1265 | Data truncated for column 'date' at row 3                                                                           |
| Warning | 1366 | Incorrect integer value: 'https://www.shogi.or.jp/tsume_shogi' for column 'steps' at row 3    |
| Warning | 1261 | Row 3 doesn't contain data for all columns                                                                          |
略
| Warning | 1062 | Duplicate entry '2017' for key 'PRIMARY'                                                                            |
| Warning | 1265 | Data truncated for column 'id' at row 13                                                                            |
| Warning | 1265 | Data truncated for column 'date' at row 13                                                                          |
| Warning | 1366 | Incorrect integer value: 'https://www.shogi.or.jp/tsume_shogi' for column 'steps' at row 13 |
| Warning | 1261 | Row 13 doesn't contain data for all columns                                                                         |
| Warning | 1062 | Duplicate entry '2017' for key 'PRIMARY'                                                                            |
+---------+------+---------------------------------------------------------------------------------------------------------------------+
64 rows in set (0.00 sec)

あととりまSELECT

MariaDB [shogi]> select * from data;
+------+------------+--------------+-------+-------+------+
| id   | date       | title        | maker | steps | url  |
+------+------------+--------------+-------+-------+------+
|    1 | 0000-00-00 | maker        | steps |     0 | NULL |
| 2017 | 0000-00-00 | 内藤國雄     | 11    |     0 | NULL |
| 2018 | 0000-00-00 | 屋敷伸之     | 11    |     0 | NULL |
| 2019 | 0000-00-00 | 谷川浩司     | 11    |     0 | NULL |
| 2020 | 0000-00-00 | 谷川浩司     | 11    |     0 | NULL |
+------+------------+--------------+-------+-------+------+
5 rows in set (0.00 sec)

なるほど…。俺はこのコマンドはカラム名から判断してなんかいい感じに処理してくれたりすんのかなとか思ってたけどそういうわけじゃないみたい。

  • csvの最初の行に記載してた列名もテーブルに読み込もうとしてエラー
  • csv内にid列に対する列がないのでその分読み込み列が一個ずつ前にずれた。
  • id列は数え上げint主キーなので年の最初の行だけ読み込んで以降はエラー

みたいな感じかなぁ。csvの最初の行消して、id列を追加してもう一回やってみよう。

MariaDB [shogi]> drop table data;
Query OK, 0 rows affected (0.12 sec)

MariaDB [shogi]> show tables;
Empty set (0.00 sec)

MariaDB [shogi]> create table data ( id int not null auto_increment, date date,  title text, maker text, steps int, url text, primary key (id));
Query OK, 0 rows affected (0.00 sec)

MariaDB [shogi]> load data local infile "shogi.csv" into table data fields terminated by ',';
Query OK, 1243 rows affected (0.30 sec)
Records: 1243  Deleted: 0  Skipped: 0  Warnings: 0

お、いけたっぽい。

MariaDB [shogi]> select * from data where id=1234;
+------+------------+--------------------------------------------------------------+--------------+-------+--------------------------------------------------------------+
| id   | date       | title                                                        | maker        | steps | url                                                          |
+------+------------+--------------------------------------------------------------+--------------+-------+--------------------------------------------------------------+
 |1234 | 2020-08-16 | 2020年8月16日の詰将棋(村田顕弘作、11手詰)                  | 村田顕弘     |    11 | https://www.shogi.or.jp/tsume_shogi/everyday/202081611.html
+------+------------+--------------------------------------------------------------+--------------+-------+--------------------------------------------------------------+
1 row in set (0.00 sec)

おお!いいんでないかな?よっしゃよっしゃ、今日はここまで~。こっからだなぁ~。

カテゴリー: したい | タグ: , | コメントする