ラベル MySQLのデータをGAEへ転送 の投稿を表示しています。 すべての投稿を表示
ラベル MySQLのデータをGAEへ転送 の投稿を表示しています。 すべての投稿を表示

2008年10月4日土曜日

Primary Key と Key_name ~MySQLのデータをGAEへ

データの入ったMySQLテーブルの内容を Google App Engine の Cloud に転送することができた。

図のData Viewer の画面であると新たに追加した Model が List に表示されるまでに少しタイムラグがあるため、作業中の動作確認は Logs の画面を監視して行なった。



今回、30個程度のテーブルを対象に作業を行なったが、RDBMS のキー項目とGoogle App Engine の Key_name の対応は以下のようになった。
Key_name は設定したが、parent は設定しなかった。


col = ""
bid = ""
cid = ""
content_id = ""
session_id = ""
menuid = ""
client_id = ""
time = ""
for r in rr:
if r.column_name == 'id' or r.column_name == 'cid':
key_name = 'id' + self.request.get(r.column_name)
j = clazz(key_name = key_name)

if r.column_name == 'cid' : cid = self.request.get(r.column_name)
if r.column_name == 'content_id': content_id = self.request.get(r.column_name)
if r.column_name == 'bid' : bid = self.request.get(r.column_name)
if r.column_name == 'time' : time = self.request.get(r.column_name)
if r.column_name == 'session_id': session_id = self.request.get(r.column_name)
if r.column_name == 'menuid' : menuid = self.request.get(r.column_name)
if r.column_name == 'client_id' : client_id = self.request.get(r.column_name)

if menuid and client_id:
key_name = 'id' + menuid + client_id
j = clazz(key_name = key_name)

if session_id and time:
key_name = 'id' + time + session_id
j = clazz(key_name = key_name)
if content_id:
key_name = 'id' + content_id
j = clazz(key_name = key_name)
if cid and bid:
key_name = 'id' + bid + cid
j = clazz(key_name = key_name)

2008年10月3日金曜日

トランザクションとデータ確認2 ~MySQLのデータをGAEへ

322 レコードのデータを 5 件づつ分けて POST したはずが、件数が合わない。

MySQL からColud へのデータの POST に較べれは、Cloud の一部のキーとなる項目データを取得して、 MySQLに格納するようにするのは工数は少なそうなので、Download 側も作成することに。


Python(Cloud , Google App Engine )
件数とキー項目(key_name)の表示

if self.request.get('cmd') == "columns":
rr = db.GqlQuery("select * from Information_schema_columns")
for r in rr:
self.response.out.write( r.key().name()+"<br>")
self.response.out.write( "count(*) = " + str(rr.count() ))

PHP(MySQL)
Cloud にアクセスし、リストされたデータを取得し、MySQL用のinsert文のSQL を作成し、表示(行末の余計なデータは手動削除)
$req =& new HTTP_Request("http://xxxx/sign?cmd=columns");
if (!PEAR::isError($req->sendRequest())) {
$imgList = $req->getResponseBody();
}
$dd = explode("<br>", $imgList) ;

$sql = "insert into `gae_columns` ( `column` ) values " ;
foreach ($dd as $d) {
$sql_values .= "( '".$d."' )," ;
}


MySQL に gae_column というテーブルを作成し、これに Cloud からの一覧データを挿入。
・MySQL に取得後のデータの確認用SQL
- 一覧

SELECT concat(table_name,'.',column_name) FROM
information_schema.columns i ,
joomlaj.gae_columns g
where i.table_schema ='joomlaj'
and concat('joomlaj_',table_name,'.',column_name) = g.column

- 不足分のリスト

SELECT concat(table_name,'.',column_name)
FROM information_schema.columns i
where i.table_schema ='joomlaj'
and concat('joomlaj_',table_name,'.',column_name) not in
(select g.column from joomlaj.gae_columns g)

やはりこうした作業は RDBMS が格段に優れる。

2008年10月2日木曜日

Dynamic Datastore MySQLのデータをGAEへ

information_schema スキーマのcolumns テーブルについては以下のように決め打ちで対応した。
Datastore 側の key_name にはスキーマ、テーブル、カラム名を結合したものを設定した。

key = information_schema_columns.table_schema + "_"
key += information_schema_columns.table_name+ "."
key += information_schema_columns.column_name

Information_schema_columns.get_or_insert(key,
table_catalog = self.request.get('table_catalog'),
table_schema = self.request.get('table_schema'),
table_name = self.request.get('table_name'),
column_name = self.request.get('column_name'),
ordinal_position = ordinal_position,
column_default = column_default,
is_nullable = self.request.get('is_nullable'),
data_type = self.request.get('data_type'),
character_maximum_length = character_maximum_length,
character_octet_length = character_octet_length,
numeric_precision = numeric_precision,
numeric_scale = numeric_scale,
character_set_name = self.request.get('character_set_name'),
collation_name = self.request.get('collation_name'),
column_type = self.request.get('column_type'),
column_key = self.request.get('column_key') ,
extra = self.request.get('extra'),
privileges = self.request.get('privileges'),
column_comment = self.request.get('column_comment'))

けれども、この情報を利用してデータを転送する汎用的なものを作成しなければならない。
RDBMSには動的SQLという仕組みがあるが、 Datastore ではどのように対応したらいいのであろうか。

Pythonでリフレクションする」*1 などと参考にいろいろと試行錯誤、ようやくそれらしいものができた。
苦労したのはまず、

1.  動的に Class を作成するには ?

clazz = globals()[cls.capitalize()]
obj = clazz()

 
2.  動的に作成できた Class の Attribute を動的に作成するには ?

setattr


3. get_or_insert() でなくて、単純に put() するときの key_name の指定方法 ?

4. key_name にはなにを設定するか ?

Joomla! では id あるいは cid 列を設定しているようなので、まずはこれらを利用することに。


def post_mysql_data(self,cls):
clazz = globals()[cls.capitalize()]
obj = clazz()
table = cls
rr = db.GqlQuery("select * from Information_schema_columns where table_name = :1", table )

col = ""
for r in rr:
if r.column_name == 'id' or r.column_name == 'cid':
column_value = self.request.get(r.column_name)
key_name = 'id' + column_value
j = clazz(key_name = key_name)

if j:
for r in rr:
column_value = self.request.get(r.column_name)
if r.data_type == 'varchar' or r.data_type == 'text' or r.data_type == 'longtext' :
if column_value : setattr(j,r.column_name,column_value)
if r.data_type == 'bigint' or r.data_type == 'tinyint' or r.data_type == 'int' :
if column_value : setattr(j,r.column_name,int(column_value))
if r.data_type == 'datetime':
if column_value :
if column_value == '0000-00-00 00:00:00':column_value = '1901-01-01 00:00:00'
column_value = datetime.datetime.strptime(column_value,'%Y-%m-%d %H:%M:%S')
setattr(j,r.column_name,column_value)
col = j.put()


*1  shisashiの開発日記 http://shisashi.blogspot.com/

information.schema.columns MySQLのデータをGAEへ

拡張機能のライブラリ Joomla! Extensions Directory の
Administration - Database Management の中の
を使うと、 Joomla! というCMSの Administration 画面で phpMyAdmin ライクの操作を行なうことができる。
テーブル構造から class の定義の変換についてはオリジナルの components を作成してみたが、以降はこの Extention Components をベースにすることにした。

PHP 側から MySQL のデータを Google App Engine の Cloud に POST して、それを Python側で受けて datastore に put()  するフローとなる。

事前に各model の定義は作成しておいたとしても、datastore に put する際に column ごとにデータの型が intger なのか text なのか、わかっている必要がある。

Cloud 側のデータの型は数字もすべてテキストとし保存してしまってもよいのかもしれないが、いずれにしろまず、列情報を持つ MySQL のテーブルを Cloud に転送する第1ターゲットとすることにした。


SELECT * FROM information_schema.columns where table_schema ='joomlaj' order by table_name, ordinal_position limit 0,10

MySQLのデータをGAEへ

テンプレートの良し悪しで画面の感じがまったくかわってしまう。
PHP で書かれている Joomla とういうCMSのテンプレートの質が高い。また拡張ライブラリが充実している。

GAE にこれらのテンプレートを応用しようとした場合、 やはり Joomla 側のキーとなるいくつかのテーブルと同様のものを Cloud に作成する必要がある。

Joomla! の components の作成手順を参考にまずテーブルに対応する class の定義を作成するようにした。 以下がまず作成した対応一覧。

if ($data_type == "bigint" ) { $datastore_type = " = db.IntegerProperty()" ;}
if ($data_type == "tinyint") { $datastore_type = " = db.IntegerProperty()" ;}
if ($data_type == "int" ) { $datastore_type = " = db.IntegerProperty()" ;}
if ($data_type == "varchar") { $datastore_type = " = db.StringProperty()" ; }
if ($data_type == "text") { $datastore_type = " = db.TextProperty()" ; }
if ($data_type == "longtext"){ $datastore_type = " = db.TextProperty()" ; }
if ($data_type == "datetime"){ $datastore_type = " = db.DateTimeProperty()" ; }
views/auto/tmpl/defaul.php



Swift UI チュートリアル Loading watchOS が終わらない?

Loading watchOS が終わらない? ディスク容量の残量が少ないので不要なシュミレーターを削除したとこころ watchOSのものが全部なくなってしまっていた。 WatchOS を削除して再度インストールしても復活せず。 Create a new simulator で ...