SQL の確認

Posted by muchag | OpenPNE 3.x,Symfony 1.x | 2015-10-08 (木) 18:34:07

発行されている SQL 文を確認する方法。

【環境】
OpenPNE:3.8.15
Symfony:1.4.13
doctrine:1.2.4
モデル

モデル生成時に自動的に生成される Table クラスで書く場合。

  1. $result = $this->createQuery('p')
  2.     ->leftJoin('p.Translation t WITH t.lang = ?', $culture)
  3.     ->andWhere('p.id = ?', 1)
  4.     ->execute();

上記のようにすることで目的のレコードを取得できるけど
createQuery メソッドで Doctrine_Query が返ってきているので
最後の execute メソッドを getSqlQuery に変更することで、生 SQL 文を取得できる。

  1. echo $this->createQuery('p')
  2.     ->leftJoin('p.Translation t WITH t.lang = ?', $culture)
  3.     ->andWhere('p.id = ?', 1)
  4.     ->getSqlQuery();
実際に利用してみて思った
  1. $query = $this->createQuery('p')
  2.     ->leftJoin('p.Translation t WITH t.lang = ?', $culture)
  3.     ->andWhere('p.id = ?', 1);
  4.  
  5. echo $query->getSqlQuery();
  6.  
  7. $result = $query->execute();

こういう風に記述してやると見やすい。

色々な記事で、execute() を切り離して記述しているのは
こういうことがあるからかも?

OpenPNE 3.x,Symfony 1.x | 2015-10-08 (木) 18:34:07 |

SoftDelete

Posted by muchag | OpenPNE 3.x,Symfony 1.x | 2015-09-06 (日) 17:41:37


SoftDelete:日本語版

レコードを削除する際に、本当に削除(物理削除)するのではなく
削除フラグを立てることによって、削除モードにする(論理削除)機能。

【環境】
OpenPNE:3.8.15
Symfony:1.4.13
doctrine:1.2.4
設定
ProjectConfiguration

ここまで実装方法などについて書いてきましたが、実はこれだけだと動きません。
Doctrineのデフォルトの設定では、Doctrine_Queryを実行前後で修正することが出来なくなっており、そこを設定してあげる必要があります。この設定の方法がsymfony 1.0とsymfony 1.1で変わってきます。

symfony 1.1ではProjectConfigurationクラスに設定を記述します。

アシアルブログ:Doctrineで論理削除を意識せずに扱う

ProjectConfiguration.class.php
  1. class ProjectConfiguration extends sfProjectConfiguration
  2. {
  3.   protected $plugins = array('sfDoctrinePlugin');
  4.  
  5.   public function configureDoctrine($manager)
  6.   {
  7.     $manager->setAttribute(Doctrine::ATTR_USE_DQL_CALLBACKS, true);
  8.   }
  9. }
OpnePNE3

OpenPNE3 では、こういう設定を追加する場所が用意されているっぽい。
まだ、成功体験をしていないので、本当にこれでよいかは不明。

(openpne3)\config\ProjectConfiguration.class.php
  1. public function setupProjectOpenPNEDoctrine($manager)
  2. {
  3.     // You can write your own configurations.
  4.  
  5.     // In default, OpenPNE uses foreign key.
  6.     // If you want not to use foreign key, comment out the following configuration:
  7.     // $manager->setAttribute(Doctrine::ATTR_EXPORT, Doctrine::EXPORT_ALL ^ Doctrine::EXPORT_CONSTRAINTS);
  8.  
  9.     $manager->setAttribute(Doctrine::ATTR_USE_DQL_CALLBACKS, true);
  10. }
schema
schema.yml
  1. Category:
  2.   actAs:
  3.    - SoftDelete
設定変更

カラム名やデータ型を変更したい場合は、下記のように記述すればよいみたい。
Symfony world:Doctrine SoftDelete behavior usage
→この記事のコメント投稿内情報。未検証。

  1. Category:
  2.   actAs:
  3.     SoftDelete:
  4.       name: is_deleted
  5.       type: datetime

力技でやっている人もいるみたい。
@chisei のはてなブログ:Doctrineの論理削除

マニュアルとの差異

このように設定することで、当該テーブルへ deleted_at カラムが追加される
んだけど・・・

公式マニュアル では、delete カラムが追加される、とされている。
データ型も、公式マニュアルでは、TYNYINT とあるけど、実際は DATETIME になる。
バージョンの問題かしらね~。

データ挿入

んで、実際に試してみた。
CSV で、データを突っ込む際に、deleted_at カラムには null を指定しておいたところ
当該カラムの値は 0000-00-00 00:00:00 となった。

CSV から Null を放り込む方法

文系プログラマによるTIPSブログ:MySQLのload dataで日付型にnullをセットする
こちらの記事がビンゴ!

  1. LOAD DATA
  2.     LOCAL INFILE 'data.csv'
  3.     INTO TABLE [table_name]
  4.     FIELDS TERMINATED BY ','
  5.     ENCLOSED BY '"'
  6.     SET
  7.         deleted_at = nullif(deleted_at, '0000-00-00 00:00:00')
  8. ;

上記記事では、指定項目がもっといっぱいあったけど
ひとまず、私の今回の環境およびデータでは、上記 SQL にて、
無事に daleted_at カラムへ Null 値を放り込めた。

nullif

どうやら第2引数に、データ型に合わせたデフォルト値を設定するみたい。
なので、その他のデータ型は下記の通り。

  1. SET
  2.         datetime = nullif(datetime, '0000-00-00 00:00:00')
  3.         date = nullif(date, '0000-00-00')
  4.         time = nullif(time, '00:00:00')
データ取得
  1. $result = $this->createQuery('c')
  2.     ->execute();

データ取得を試みたところ
取得データ数は 0 。

SQL 確認

SQL の確認 のごとく、発行された SQL 文を確認すると、
ちゃんと WHERE 句が付記されている。

  1. WHERE (o.deleted_at IS NULL)

※エイリアスに p を指定しているのに、テーブル名の先頭文字 o をエイリアスにされているが気になるけど。。。

エイリアス o

これは、こちらの指定した DQL から Doctrine が SQL を生成する際に、
指定されたテーブルを順番に o1, o2, o3, … と再指定しているためだった。

その o も、恐らく、テーブル名の頭文字を取っていると思われる。
OpenPNE3 の場合、テーブル接頭辞を付けているため
全テーブルが op_ で始まるのよね。

原因

Doctrine が NULL を探しているのに対して、
データ側は ‘0000-00-00 00:00:00’ という値であるため
スルーされていた。

解決

上記 データ挿入→CSV から Null を放り込む方法 を用いて
値を Null にしてやることで、ちゃんとデータを取得できるようになった。

過去の対応策
  1. $result = $this->createQuery('p')
  2.     ->andWhere('p.deleted_at = ?', '0000-00-00 00:00:00')
  3.     ->execute();

これで一応拾ってくることはできた。

とりあえずはこれでいくしかないけど。。。意味なーい!
いつか解明しなければ。。。
(やっと解明できた)

エイリアス

ちなみにテーブルエイリアスを付けないと、上記記述でも拾ってこない。

  1. // NG
  2. $result = $this->createQuery()
  3.     ->andWhere('deleted_at = ?', '0000-00-00 00:00:00')
  4.     ->execute();

必ずエイリアスをつける必要があります。
ただしこれはSELECT限定で、DELETEのときはエイリアスがなくても動くようです。

アシアルブログ:Doctrineで論理削除を意識せずに扱う

OpenPNE 3.x,Symfony 1.x | 2015-09-06 (日) 17:41:37 |

SQLSTATE[HY000]: General error: 1005 Can’t create table

Posted by muchag | OpenPNE 3.x,Symfony 1.x | 2015-05-21 (木) 22:49:18

【環境】
Symfony:1.4.13
OpnePNE:3.8.15
状況

OpenPNE3 のプラグインを開発していて、DB の再構築を行ったところ
下記のようなエラーメッセージが出た。

エラーメッセージ
SQLSTATE[HY000]: General error: 1005 Can’t create table ‘database_name.#sql-16e8_55a’
(errno: 150).
Failing Query:
“ALTER TABLE op_my_hoge ADD CONSTRAINT op_my_hoge_parent_id_op_my_parent_id FOREIGN KEY (parent_id) REFERENCES op_my_parent(id)”.
Failing Query:
ALTER TABLE op_my_hoge ADD CONSTRAINT op_my_hoge_parent_id_op_my_parent_id FOREIGN KEY (parent_id) REFERENCES op_my_parent(id)
原因

よく見てみると
op_my_hoge.parent_id と op_my_parent.id のデータ型が異なっていた。

OpenPNE 3.x,Symfony 1.x | 2015-05-21 (木) 22:49:18 |

Symfony 1.x のデバッグ

Posted by muchag | Eclipse,OpenPNE 3.x,Symfony 1.x | 2015-04-27 (月) 12:19:28

自作のプログラムなら簡単にデバッグできるけど
Symfony のようなフレームワークは、よくわからなかったので、調べてみた。

【環境】
Eclipse: Luna Service Release 1 (4.4.1)
Symfony: 1.4.13
デバッグの構成

[実行]-[デバッグの構成]
[PHP Web アプリケーション]
初めての場合は、自動で新規構成が表示される。
2つ目以降は、左ペインツールバーにある [新規の起動構成] をクリック。

サーバー
名前

自由。

サーバー

任意に選択。

未設定の場合は、Xdebug 再び! 参照。

ファイル

[参照] から、(Symfony プロジェクト)\web\index.php を選択すると
/(Symfony プロジェクト)/web/index.php
と入力される。

2015-12-17 追記 ここから

今日は、上述のやり方ではできなかった。
Xdebug 再び! に追記しておいたので、参照。

2015-12-17 追記 ここまで
URL

[自動生成] のチェックを外す。
すると、右のテキストボックスがアクティブになる。

左のテキストボックスには「http://localhost/」と入っている。

これで、XAMPP の htdocs までのパスは確保されているので
右のテキストボックスに、それ以下を記述。
「/(appname)/index.php」(自分の環境に適宜合わせる)

適用

[適用] をクリック。

参考サイト

Layer8:Windows上のEclipseでsymfonyをデバッグする方法

Eclipse,OpenPNE 3.x,Symfony 1.x | 2015-04-27 (月) 12:19:28 |

XAMPP 1.7.3 へインストール

Posted by muchag | OpenPNE 3.x | 2012-04-30 (月) 21:24:53

XAMPP 1.8.1 へインストール
こちらの方が新しい記事。
 
まずはローカルへのインストールから。

【環境】
[XAMPP] 1.7.3
[symfony] 1.4
[OpenPNE] 3.8.0

OpenPNE3.8 セットアップ手順 に従って作業。
 

DL

http://www.openpne.jp/pne-downloads/ より github へ移動し、ソースを DL 。

ZIP ファイルを DL してきた。
2012-04-30 現在
openpne-OpenPNE3-OpenPNE-3.8.0-0-g8c3a808.zip
 

インストール
配置
XAMPP ディレクトリ/htdocs

と同階層へ配置。

ディレクトリ名を適宜変更。
 

設定ファイル
OpenPNE3 ディレクトリ/config/OpenPNE.yml.sample
OpenPNE3 ディレクトリ/config/ProjectConfiguration.class.php.sample

以上2ファイルをコピーして .sample の部分をファイル名から消去し、設定ファイルを作成。
 

OpenPNE3 ディレクトリ/config/OpenPNE.yml
base_url
  1. # SNS の URL
  2. # URL of the SNS
  3. base_url: "http://localhost/openpne3"

 

DB:テーブルプレフィクス
  1. # テーブル名のプレフィックス (例: table_prefix: "op_")
  2. # Table name prefix (e.g: table_prefix: "op_")
  3. table_prefix: ""
  4. table_prefix: "op_"

推奨通り 190行目を op_ に設定。
 

symfony コマンド

私は PHP へのパスを通していないので、
手順書にちょっと手を加えて、PHP へのフルパスから記述。

  1. >I:\xampp\php\php.exe symfony openpne:install

* 使用する DBMS (mysql, pgsql, sqlite から選択。ただし mysql 以外は未サポート)
* データベース名
* データベースへの接続用ユーザ名
* データベースへの接続用パスワード(未入力可)
* データベースサーバのホスト名(localhost など)
* データベースサーバのポート番号(未入力可)
* (DBMS に MySQL を選択し、サーバホスト名に localhost を指定した場合)使用するソケットへのパス(未入力可)

手順書には上記順序で記載されていたが
実際は
* 使用する DBMS
* データベースへの接続用ユーザ名
* データベースへの接続用パスワード(未入力可)
* データベースサーバのホスト名(localhost など)
* データベースサーバのポート番号(未入力可)
* データベース名
* 使用するソケットへのパス(未入力可)
の順で入力。

最後に (Y/n) で聞かれるので、y を入力して Enter を叩くと
ズラズラとログが流れ
>> installer installation is completed!
と表示され、インストールが完了する。
 

開発環境用ファイルを削除
  1. >I:\xampp\php\php.exe symfony project:clear-controllers

 

設定
OpenPNE 3.x | 2012-04-30 (月) 21:24:53 |