ページビューの合計

2023年4月12日水曜日

PostgreSQLの日付フォーマット違いでCSVインポート時にエラー

日本から受領したCSVデータをローカルのPostgreSQLにインポートしたらなぜか

date/time field out of range "1/31/2022"

というエラーメッセージが、範囲外って言われても?

Error “date/time field out of range” occurs for MDY date style

えっ?

ひょっとして、 "31/1/2022"って書かないとダメってこと?

これが正解でした。

いやおかしい、私の環境では問題なく、他の担当の環境で発生しました。

同じPostgreSQLでバージョンも15なんですが??? 

釈然としませんが忘備録としてメモしておきます。

 

2023年4月10日月曜日

Laravel 自習 Model、マイグレーションファイルそしてシード

以前の記事でデータベースにアプローチする方法を記載しました。 

  1. DBクラス(クエリビルダ): Controller内に記述します。
  2. Eloquent(ORM) :Modelを生成して使用します。

MVCモデルを使って実装していきたいので、Eloquent(ORM)「エロクアント」の使い方について学んでいきます。

EloquentはORM(Object-Relational Mapping) です。
RDBのテーブルやレコードをPHPのオブジェクトのように扱うことが出来るようになります。
 
公式ドキュメントには以下の記述があります。
Eloquentを使用する場合、各データベーステーブルに対応する「モデル」があり、そのテーブル操作に使用します。Eloquentモデルは、データベーステーブルからレコードを取得するだけでなく、テーブルへのレコード挿入、更新、削除も可能です。
上記の通り、Eloquentを使用するには対象のテーブルに対応するモデルがあり、それに対して操作を行うとのことです。
 
また前回の記事にも書きましたが、モデル名はテーブル名に対応したものにする必要があります。
再度書いておきます。
テーブル名
別の名前を明示的に指定しない限り、クラスの複数形の「スネークケース」をテーブル名として使用します。

 

Modelの作成

とりあえずModelを作ってみます。

Userモデルを作ろうと思ったのですがなぜか最初から存在しています。
Productモデルを代わりに作成します。

$php artisan make:model Product

app/Models/Product.phpが以下のように生成されました。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    use HasFactory;
}

 

マイグレーションファイルの作成

マイグレーションはデータベースのバージョン管理のようなもので、チームがアプリケーションのデータベーススキーマを定義および共有できるようにします。
上記の公式の説明があるようにデータベース特にテーブルのバージョン管理みたいなものです。開発中あるいは開発後でもバグ対応、仕様追加、パフォーマンスのためにテーブル構造は変わっていきます。 
テーブルの変更を適用するためのSQL文を作成して実行しても構いませんが管理が大変になっていきます。
最初からテーブル構造のバージョン管理ができる機能があるのは便利ですね。
変更があってもレポジトリから最新のマイグレーションファイルを取得してartisanコマンドを実行すれば最新の状態になります。 

実際にModel Productに対応したテーブルを作成するためのマイグレーションファイルを生成してみます。

$php artisan make:migration create_products_table

こんな感じでコマンドを実行するとdatabase\migrations/2023_04_10_075612_create_products_table.phpが以下のように生成されました。

<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('products', function (Blueprint $table) {
            $table->id();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('products');
    }
};

ただこれだけだと、idとタイムスタンプしかないので編集していきます。

プライマリーキーは、product_idにしました。以下のように設定します。

protected $primaryKey = 'product_id';

マイグレーションファイル

$php artisan migrate

を実行すると以下のようにテーブルが作成されました。

コマンド実行してテーブルを新規作成する

DBを確認すると以下のようにテーブルが作成されていました。

作成されたテーブル

シーダーを使った初期データ登録

 
開発を行うに当たってマスターテーブルの初期データやテスト用のデータが必要となります。
 
Product用のシーダーを作成します。
$php artisan make:seeder ProductSeeder
を実行すると
database/seeders/ProductSeeder.phpが生成されました。

<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class ProductSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        //
    }
}

上記のようにrun()メソッドがあるだけです。

ここに初期データを記載していきます。Eloquentを使って1件のデータを作成してみます。

<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use App\Models\Product;

class ProductSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        Product::create([
            'product_name' => 'Test1',
            'product_price' => 100,
        ]);
    }
}

$php artisan db:seed --class ProductSeeder

を実行します。

想定したレコードがproductsテーブルに挿入されました。

設定したのは、”product_name”、”product_price” のみです。他のカラムは自動的に設定されました。

プライマリーキーも自動で1が設定されています。


 

2023年4月8日土曜日

Laravel 自習 データベースにアプローチする方法

前回でアプリ用のDBの作成が終わりました。

DB用の接続情報を設定してからModelとマイグレーションファイルを作ってみます。

DB接続情報の記述

.envファイルの11 - 16行目がDB接続情報の記述欄です。

デフォルトでMySQLになっているので、DB名、ユーザ名、パスワードだけを修正すれば良いです。

.envファイルのDB接続情報

 

Modelの作成

フレームワークの中で直接SQL文を書くものもありますが、大体のフレームワークではテーブルを隠蔽してオブジェクトとしてプログラムから操作できる場合が多いですね。
ただテーブル間のリレーションがシンプルなら良いのですが、以前のプロジェクトでサブクエリとか使いまくって酷く歪なテーブルリレーションのプロジェクトに当たったことがあります。
思わず「テーブルの正規化とかスタースキーマとか勉強して出直して来い」って言いたくなるほどでした。そういうプロジェクトには適用しずらいでしょうね。
閑話休題
 
Laravelには2種類のデータベースにアプローチする方法があるようです。
 
DBクラス(クエリビルダ)
 
DBクラスを使う方法
 
ただ、この機能はControllerの中で呼び出すみたいですね。
Controllerの中でDBクラスを呼び出して必要なデータを取得してから、Viewに渡して結果を表示する感じです。
 
use Illuminate\Support\Facades\DB;の機能です。
SQL文をそのまま書きます。
一般形は
$items = DB::命令文の種類('実際のSQL文', パラメータ);
実際のSQLの中に":キー"という書式を埋め込むことができます。

これはSQL文中にある:idのように、あとからそこに値を割り当てるものでプレースホルダといいます。
後からくる値(パラメータで渡す)のために場所を取っておく感じです。
単なる値でも複数の値を配列で渡すこともできます。

例:
  • DB::select('select * from テーブル名 where id = :id', $id);
  • DB::insert('insert into テーブル名 (id, name) values (:column1,:column2)', $param);
  • DB::update('update テーブル名 set column1 = :column1, column2 = :column2' where id = :id, $param);
  • DB::delete('delete * from テーブル名 where id = :id', $id);

クエリビルダを使う方法
この機能もControllerの中で呼び出すみたいですね。
Controllerの中でクエリビルダを呼び出して必要なデータを取得してから、Viewに渡して結果を表示する感じです。
 
上記のDBクラスは直接SQL文が書けるので、SQL文が分かっている人にとっては便利でしょうね。
SQLクライアントを使ってSQL文を実行して想定した結果が得られることを確認してからソースコードにコピペして変数の部分だけパラメータ渡しにすれば良いです。

私的にはこれで全然問題ないのですが、
  • SQL文にパラメータの値を組み込んで最終的なSQL文を生成するので正しいSQL文が実行されているか分かりずらい。
  • 渡す値によっては予想外のSQL文が実行される危険がある。
  • PHPでプログラムを書いているのにDBアクセスのところだけ別の言語で書かないといけないのはストレスになる。
といった理由でクエリビルダが生まれたようです。
DBクラスと違って直接SQL文を書くことはなく、必要なメソッドを呼び出してパラメータを渡すことでSQL文を生成してくれます。
なので最終的なSQL文は表面上には現れません。
 
use Illuminate\Support\Facades\DB;を使います。
 
DB::table(テーブル名) 
でビルダ(\Illuminate\Database\Query\Builder)を取得します。 
ビルダはSQLクエリ文を生成するための機能を提供します。

例:
  • DB::table(テーブル名)->get();
  • DB::table(テーブル名)->insert($param);
  • DB::table(テーブル名)->where('id', $id)->update($param);
  • DB::table(テーブル名)->where('id', $id)->delete();
 
対象のテーブルのビルダを取得して用意されてるメソッドを使って操作するのでSQL文の書き間違いは無くなるでしょうね。
ただクエリビルダで複数テーブルをジョインするような場合はどうするんだろう?
 
Eloquent(ORM)
EloquentはORM(Object-Relational Mapping)で「エロクアント」と読みます。
DBのテーブルやレコードをオブジェクトとして扱える仕組みです。 

Eloquentを使用する場合、各データベーステーブルに対応する「モデル」があり、そのテーブル操作に使用します。Eloquentモデルは、データベーステーブルからレコードを取得するだけでなく、テーブルへのレコード挿入、更新、削除も可能です。

 ようやくModelが出てきました。

モデルは通常app\Modelsディレクトリにあり、Illuminate\Database\Eloquent\Modelクラスを拡張します。make:model Artisanコマンドを使用して、新しいモデルを生成します。
$php artisan make:model モデル名

でモデルを生成できます。

1点注意が必要です。 モデル名はテーブル名に合わせる必要があります。
 例:
モデル名 テーブル名
Flight flights
AirTrafficController air_traffic_controllers
 
公式に以下の説明があります。

クラス名の複数形をスネークケースにしたものが自動的にテーブル名と見なされます。

これに適合しない場合はモデルのtableプロパティに設定します。

テーブル名
上記の例をちょっと見て、どのデータベーステーブルがFlightモデルに対応するかをEloquentに知らせていないことにお気づきかもしれません。別の名前を明示的に指定しない限り、クラスの複数形の「スネークケース」をテーブル名として使用します。したがって、この場合、EloquentはFlightモデルがflightsテーブルにレコードを格納し、AirTrafficControllerモデルはair_traffic_controllersテーブルにレコードを格納すると想定できます。

モデルの対応するデータベーステーブルがこの規約に適合しない場合は、モデルにtableプロパティを定義してモデルのテーブル名を自分で指定できます。
以下の気になる記述が公式にありました。
はっきり言って嫌いですね。 下手なテーブル定義の温床です。
きっちりテーブル設計すれば、”id”なんていう主キーを定義する必要はないはずです。
これについてはアンチパターンとして議論がされているようです。
主キー
Eloquentは、各モデルの対応するデータベーステーブルにidという名前の主キーカラムがあることも想定しています。必要に応じて、モデルのprotected $primaryKeyプロパティを定義して、主キーとして機能する別のカラムを指定できます。
主キーについては、さらに下記の記述があります。
これは問題ないですね。PostgreSQLなどだと主キーにシリアルを設定して複数ユーザが同時にレコード挿入しても自動的にバッティングしない値になることが保証されています。
設計の都合上、非数値にしたい場合でも設定が可能です。
さらに、Eloquentは、主キーが増分整数値であることも想定しています。これは、Eloquentが主キーを自動的に整数にキャストすることを意味します。非インクリメントまたは非数値の主キーを使用する場合は、モデルにpublicの$incrementingプロパティを定義し、falseをセットする必要があります。
この記事では、モデルの作成、マイグレーションファイル作成、シードの作成まで行こうと思っていましたが長くなってきたので次の記事で書くことにます。
 

2023年4月7日金曜日

Laravel 自習 DB作成(phpMyAdmin)

Laravelの実行、デバッグ環境はLaragonにしました。

アプリを起動して画面で右クリック→MySQL→phpMyAdminを選択してもなんか良く分からんWebページが表示されるだけで起動しません。

Laragon で PHP による動的サイトの開発環境を構築

によれば

https://www.phpmyadmin.net/downloads/

ここから最新版をダウンロードして「C:\laragon\etc\apps」に展開すれば良いようです。

フォルダ名は”phpMyAdmin”

もう一度起動すると問題なくログイン画面になります。


ユーザ名:root

パスワード:(空白)

でログインできます。

ログインできました。

適当にDBを作成します。

 

以前書いた気がしますが

https://web2sunny.blogspot.com/2023/03/xamppmysqldb.html

文字コード:utf8mb4
Collation:utf8mb4_bin
で良いと思います。

適当にユーザを作ります。
権限の新規作成からユーザアカウントを作成します。



 

Laravel 自習開始

改めてLaravelの学習を始めます。
バージョンは現在最新の10.xにします。

Breezeとか使わずに自分でイチから機能を組んでいきます。

プロジェクトの作成
ComposerとPHPの環境が必要です。
 

現在の状況

$composer -v
Composer version 2.4.2 2022-09-14 16:11:15 

$PHP -v
PHP 8.0.19 (cli) (built: May 10 2022 08:46:29) ( ZTS Visual C++ 2019 x64 )

Laragonのインストール

Xamppがインストール済でC:\xampp\phpにPathが通っています。

https://laravel.com/docs/10.x/releases
によるとLaravel10はPHPのバージョンが8.1 - 8.2が必要になっています。

ローカルのXampは8.0.19
Xamppのバージョンを上げておきます。
ググると
https://www.tairaengineer-note.com/xampp-update/
実はXAMPPは上書きアップデートを実行することができません。

うわ、めんどくさい

面倒なのでLaragonに変えます。

ここからダウンローダを落として実行します。
日本語にも対応しています。
普通に次へを押すだけです。






 

起動後に、「ルート」ボタンを押下すると
C:\laragon\www
をファイルエクスプローラで開きます。

ここがドキュメントルートみたいですね。

Composerのインストール

最新は2.5.5です。
https://getcomposer.org/
から最新版をダウンロードして再インストールしておきます。

インストーラを起動するとDeveloper modeとかいう謎の選択肢が表示されます。
チェックするとアンインストーラーがダウンロードされないそうです。
未チェックでいきます。っていうかそんな機能いらん。

PHPのパスがXamppの方になっているのでLaragonの配下に変えておきます。

パスを追加するようにチェックします。

Proxyは未チェックで


インストールします。


インストールが完了します。

 

版数の確認、問題ありません。

$PHP -v
PHP 8.1.10 (cli) (built: Aug 30 2022 18:05:49) (ZTS Visual C++ 2019 x64)

$composer -v
Composer version 2.5.5 2023-03-21 11:50:05

Laravelプロジェクトの作成


遠回りしたけどようやくプロジェクトの作成です。
C:\laragon\wwwの下でコマンドを実行します。
$composer create-project laravel/laravel experimental-app


http://localhost/experimental-app/public/
これでデフォルトの画面が表示されます。


 


2023年4月5日水曜日

今後のLaravelの学習に関して

公式のBootcampは正直つまらなかった。
なんか言われるままに作ってお終い。
構造とか何のために何をしてるかの説明はほとんど無し。

とりあえずランダムに覚えたいことや確認したいことを書いておきます。

・MVCに関して
・Routingに関して
・Middlewareに関して
・メールの送信機能に関して
・Auth認証機能の実装

Breezeだと最初からAuth認証機能が実装されていました。
それでも構いませんが自分でも実装できるようにしておいたほうが良いでしょう。
要件によってはロールを分けてアクセスできるページに制限をかけるようなケースもありますから。

・ファイルのアップロード
・ファイルのダウンロード

せっかくだからExcel形式でデータをダウンロードできると良いですね。
プラスPDF形式にも対応したい

・Validationに関して
・Migrationに関して
・Seedに関して
・Bladeに関して

画面を分割して、ヘッダー、フッター、ナビゲーションバーなどを共通化して読み込む感じにする。

・CSSに関して

TailWind, BootStrapの利用に関して

・検索機能に関して

・マルチ言語対応に関して

メニュー、メッセージなどを別ファイルにして読み込めるようにする


・ページネーション

・デバッグ
PHPUnit
VSCode上でデバッグ
ブラウザ上でデバッグ

・フラッシュメッセージの作り方
・Logの残し方
・セッションの管理の仕方
・CSRF保護について
・レスポンシブデザイン対応

とりあえず今のところ思いつくのはこれくらい。

小さくても良いからなんかのWebアプリで実装してみるのが良いでしょうね。


 

2023年4月4日火曜日

Laravel Bootcamp: 09. Conclusion & Next Steps

 最後の章です。
一応体験的なものはこれで終わりみたいですね。

なんとなくコーディングしただけであまり構造や知識が身に付いた感がないのが残念です。

今後の課題として色んな機能が紹介されています。

  •     Automated Testing
  •     Broadcasting (Web Sockets)
  •     Form Request Validation
  •     Queues
  •     Task Scheduling
  •     File Storage
  •     HTTP Client
  •     Database Seeding
  •     Collections
  •     Subscription Billing
  •     Administration Panels
  •     Server Management
  •     Serverless Deployment


この辺で気になるのは

  • Automated Testing
  • Form Request Validation
  • File Storage
  • Database Seeding

これでいったんBootcampは終わりとします。

 

Laravel Bootcamp: 08. Deploying

今まではローカル開発環境で実行してきましたが本番環境へのデプロイを行うようです。

Choosing a provider

デプロイするプロバイダを選択します。
PHPをホスティングを提供するプロバイダはいくつかあるようです。
Webサーバ、データベース、PHPの実行ができる環境が最低限になるでしょう。

Laravel ForgeLaravel Vaporが紹介されています。

Laravel Forge

PHPのウェブアプリをDigitalOcean, Linode, AWSなどのクラウド環境にホスティングするための環境構築を楽にしてくれるツールのようです。

Laravel Vapor
Laravel Vapor を使って Serverless な Laravel アプリケーションをデプロイする
Laravel を AWS Lambda 上で動作させることができる 有料 のツールで、Serverless な Laravel アプリケーションを構築することができるそうです。

Laravel Forge用に以下のプロバイダが紹介されています。

  •     DigitalOcean ($100 free credit available)
  •     Linode ($50 free credit available)
  •     AWS (free tier available)
  •     Vultr ($50 free credit available)
  •     Hetzner
  •     Custom VPS server


AWS以外は聞いたことがないですね。

Connecting to source control

Forgeはソースコード管理システムが必要のようです。
GitHub, GitLab, Bitbucketが紹介されています。
こだわりが無ければGitHubで良いでしょうね。

Connecting to your server provider

Forgeはサーバの構築にプロバイダのAPIキーを必要とするようです。

Creating a server

ソースコード管理システムとサービスプロバイダに接続できるようになった状態でサーバを生成します。
必要な情報を入力してサーバ生成ボタンを押すだけです。

Creating a site (optional)

Forgeは自動的に「デフォルト」サイトを生成するようです。
サーバにパブリックIPアドレス(グローバルIPアドレス)でアクセスできるようです。
簡単に確認するなら、ドメインを取得する必要がなくて便利ですね。

ドメイン名を使いたい時は、「デフォルト」サイトを削除して登録するだけのようです。

Creating a database

「デフォルト」サイトを使っている場合はアプリ用のDBの作成が必須らしいです。

Installing a repository

ちょっとわかりずらいですが、生成したサーバにソースコード管理システムからソースコードをデプロイするんだと思います。

Configuring your environment file

.env.exampleが環境に存在するはずなので、DBあるいはMail関連の設定を行います。

Configuring your deploy script

デプロイのためのスクリプトが自動生成されるようです。
そしてNode の依存関係と Vite を使用しているため、依存関係をインストールしてアセットを構築する手順を追加する必要があるようです。

Running a queue worker (optional)

Queue workerというのは何か不明です。
ググると
Laravelではキューとジョブがあります。
個々の処理がジョブでそれがキューの中に配置されて実行されるのを待っている感じです。
Laravelでジョブとキューを理解する

Laravelのキューワーカー(queue:work)はソースコード反映に再起動が必要だった件
 

Queue workerが実際にキューからジョブを取り出して実行する機能なのでしょう。
Queue workerが動きっぱなしになっているとメモリを消費するし、古いソースコードで動くことになりますね。

Running a task scheduler (optional)

タスクスケジューラ?
cronみたいなもののようですが、ここでなぜ出てくるのか不明です。

Deploying

デプロイボタンを押せば実際のデプロイが始まるようです。


では次のチャプターに行きましょう

Continue to conclusion and next steps...

2023年4月3日月曜日

Laravel Viteでnpm run buildを行っても変更が反映されない

現在は開発環境なのでnpm run devを実行します。Ctrl + Cで止めるまで起動し続けます。
開発中だからどんどんソースファイルが変わっていきますが、TailWind CSSやVue.js等の修正をリアルタイムで変換してブラウザ側で読み込めます。

本番では、ソースコードは固定のはずなので上記処理は不要です。
なのでnpm run buildを実行して問題なく動作するかと思ったら画面が崩れました。

npm run buildの実行結果

画面のデザインが崩れています


ググったらすぐに見つかりました。
Laravel Viteでnpm run buildを行っても変更が反映されない原因と対策
 

npm run devを実行中にhotファイルを作成しますが、npm run devを停止しても残ってしまう場合があるようです。

確かに"hot"ファイルが残ったままですね。

しかも$npm run buildで生成した本番環境用ファイルもpublic/build/assetsの下にあります。 

そのため今回のような現象になったようです。

public配下の状態

まずはさっくり"hot"ファイルを削除します。

そうすると問題なく画面が表示されました。



Laravel再学習

フロントエンド系の方に興味が行っていましたがまたバックエンド系に戻ってきました。 Laravelです。 かなり忘れてます、自分のブログを見ながらもう一度です。 今回はMVCパターン、そして Eloquentを使えるようになるのが目的です。 まずはプロジェクト作成から 1. Com...