検索

クリアフィルター
記事
Toshihiko Minamoto · 2020年12月7日

Arduino と RFID を使用したユーザー認証

    以前の記事では Arduino を使い始め、最終的には気象観測所のデータを表示できるようになりました。 この記事ではさらに掘り下げ、InterSystems Caché アプリケーションに対して RFID カードと Arduino を介した認証をセットアップします。   認証の委任 Caché には認証コードの書き込みを許可することで、[認証を委任](http://docs.intersystems.com/cache20161/csp/docbook/DocBook.UI.Page.cls?KEY=GCAS_delegated)するための仕組みがあります。 この仕組みを有効にするには、次の手順を実行する必要があります。 ZAUTHENTICATE ルーチンにユーザー認証コードを記述します。 このルーチンにはユーザー名/パスワードの取得、それらの検証と権限の割り当て、パスワード変更、トークン生成の 4 つのエントリポイントがあります。 詳細については、以下をお読みください。 1. Caché で委任認証を有効にします([SMP] → [System Administration] → [Security] → [System Security] → [Authentication/CSP Session Options] を開き、[Allow Delegated authentication] ボックスにチェックを入れて設定を保存します)。 2. 関連するサービスかアプリケーションの委任認証を有効にします(前者の場合は [SMP] → [Menu] → [Manage Services] → [Service] → [Allowed Authentication Methods] → [Delegated] を選択 → [Save]、後者の場合は [SMP] → [Menu] → [Manage Web Applications] → [Application] → [Allowed Authentication Methods] → [Delegated] を選択 → [Save])。 仕組み 委任認証は、委任認証が有効になっているサービスや Web アプリケーションに対してユーザーが認証される際に発生します。 1. ZAUTHENTICATE ルーチンが呼び出されます。 このルーチンのコードはユーザーによって書かれたものであり、[OS](http://docs.intersystems.com/cache20161/csp/docbook/DocBook.UI.Page.cls?KEY=RCOS_fzf-1#RCOS_B78412) への呼び出しを含む任意の Caché ObjectScript コードである可能性があります。 2. 次のステップは、ZAUTHENTICATE の呼び出しが成功したかどうかによって決まります。 ZAUTHENTICATE の呼び出しが成功し、ユーザーが ZAUTHENTICATE で認証されたのが初めてだった場合は「委任されたユーザー」が作成されます。 ZAUTHENTICATE がロールやその他の権限をユーザーに割り当てた場合は、それらがユーザープロパティになります。 ZAUTHENTICATE の呼び出しが成功し、ユーザーが ZAUTHENTICATE で認証されたのが初めてではなかった場合はそのユーザーのレコードが更新されます。 ZAUTHENTICATE の呼び出しが成功しなかった場合、ユーザーはアクセスエラーを受け取ります。 インスタンスとサービスで 2 要素認証が有効になっている場合は、ユーザーの電話番号と事業者の検索が開始されます。 これらの情報が入力されている場合は、2 要素認証が実行されます。 入力されていない場合は、ユーザーは認証されません。 ユーザー情報の出処は? 次のように、アプリケーション/サービスで有効になっている認証方法に応じた 2 つの認証方法があります。 * 委任: ユーザー名/パスワードは ZAUTHENTICATE ルーチン(GetCredentials エントリポイント)から取得され、ZAUTHENTICATE を使用して検証されます([ユーザータイプ](http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=GCAS_users#GCAS_users_types): 委任)。 委任およびパスワード: ユーザー名/パスワードは GetCredentials から取得されますが、標準の Caché ツールを使用してチェックされます(ユーザータイプ: Caché)。 次に、ZAUTHENTICATE ルーチンとそのエントリポイントを見てみましょう。 ZAUTHENTICATE これはメインルーチンであり、次の 4 つのエントリポイントで構成されています。 GetCredentials このエントリポイントはサービスで委任認証が有効になっている場合に呼び出され、ユーザーにユーザー名/パスワードの入力を求める代わりに呼び出されます。 このルーチンのコードは、ユーザー名とパスワードを(何らかの方法で)取得します。 その後、(このエントリポイントの外部で)受信したユーザー名とパスワードはユーザーから通常の方法で入力されたかのように認証されます。 ユーザー名とパスワードは、キーボードからの入力、API、外部デバイスを使用したスキャンなど、任意の方法で取得できます。 この記事では、RFID カードを使用した認証を実装します。 このエントリポイントはステータスを返します。ステータスがエラーの場合は監査ログに記録され、認証試行は拒否されます。 ただし、エラーステータス $SYSTEM.Status.Error($$$GetCredentialsFailed) が返された場合は、例外的に通常のユーザー名/パスワードの入力が続きます。 シグネチャは次のとおりです。 GetCredentials(ServiceName, Namespace, Username, Password, Credentials) Public { } 説明: * ServiceName – 接続が確立されるサービスの名前 * Namespace – ネームスペース(接続時に指定されている場合) * Username – ユーザー名 * Password – パスワード Credentials – 現在使用されていません このエントリポイントの重要な機能について説明します。 委任認証とパスワード認証の両方がサービスやアプリケーションで有効になっている場合、ユーザー名とパスワードは GetCredentials エントリポイントを介して受信されますが、それらの情報は標準のパスワード認証に使用されます(ユーザーが手動で入力した場合と同じ)。また、認証が成功した場合のユーザーは委任ユーザーではなく通常の Cache ユーザーになります。 ZAUTHENTICATE 初回認証が成功すると、ZAUTHENTICATE はロールやその他のユーザープロパティを定義します。 初回認証以外の場合はプロパティが更新されます(例えば、Roles はログインのたびに指定する必要があります)。 そのために、Properties 配列のプロパティを定型化したコードで設定する必要があります。 シグネチャは以下のとおりです。 ZAUTHENTICATE(ServiceName, Namespace, Username, Password, Credentials, Properties) Public { } Properties 配列の説明: * Properties("Comment") — コメント * Properties("FullName") — 氏名 * Properties("NameSpace") — 初期ネームスペース * Properties("Roles") — カンマ区切りのロールのリスト * Properties("Routine") — 初期ルーチン * Properties("Password") — パスワード * Properties("Username") — ユーザー名 * Properties("PhoneNumber") — ユーザーの電話番号 * Properties("PhoneProvider") — 電話会社 Properties("AutheEnabled") — 標準の 2 要素認証を有効化します(この目的のために、$$$AutheTwoFactorSMS に等しい値を設定する必要があります) ChangePassword ユーザーパスワードを変更するためのエントリポイントです。シグネチャは次のとおりです。 ChangePassword(Username, NewPassword, OldPassword, Status) Public { } 説明: * NewPassword — 新しいパスワード * OldPassword — 古いパスワード Status — パスワード変更の結果 SendTwoFactorToken 標準の 2 要素認証で使用されるものです。 リクエストの形式と認証トークンを指定します。 シグネチャは以下のとおりです。 SendTwoFactorToken(Username, ServiceName,Namespace,Application,Credentials,SecurityToken,TwoFactorTimeout,UserPhoneNumber) Public { } 説明: * Application — ユーザーが接続している CSP アプリケーションまたはルーチン * SecurityToken — ユーザーに送信されるトークン * TwoFactorTimeout — トークンの有効期限が切れる時間 UserPhoneNumber — ユーザーの電話番号 例 まずは簡単な例から始めましょう。Windows での Caché ターミナルを担う %Service_Console サービスは、ユーザー名とパスワードの入力をユーザーに要求します。 このサービスに対して委任認証を有効にしましょう。 以下は、ユーザーにユーザー名とパスワードの入力を要求する ZAUTHENTICATE ルーチン(%SYS ネームスペース内)です。 ZAUTHENTICATE(ServiceName, Namespace, Username, Password, Credentials, Properties) PUBLIC { #Include %occStatus Quit $$$OK } GetCredentials(ServiceName, Namespace, Username, Password, Credentials) Public { #Include %occErrors #Include %occStatus Do ##class(%Prompt).GetString("USER:",.Username) Do ##class(%Prompt).GetString("PASS:",.Password) Quit $$$OK } ターミナルの場合、これは通常のユーザー名認証と同じように見えます。 >USER: _SYSTEM >PASS: SYS RFID それでは、RFID による認証を見てみましょう。 考え方は単純で、Caché が暗号化されたユーザー名とパスワードをカードに書き込み、認証中に Caché がカードをスキャンして復号化し、受け取ったユーザー名とパスワードを認証に使用するというものです。 まず、Arduino Uno と [RFID-RC522](http://playground.arduino.cc/Learning/MFRC522) モジュールの回路図をご覧ください。 ![](/sites/default/files/inline/images/tutorial_rfid.jpg) [MF522](https://github.com/miguelbalboa/rfid) ライブラリを使用した [C のコードはここにあります](https://github.com/intersystems-ru/ArduinoSnippets/blob/master/Delegated/Delegated.ino)。 このコードでは、COM ポート経由で次の 2 つのコマンドを受信できます。 * Get – RFID カードのブロック 2 / 4 / 5 / 6 の内容が COM ポートに渡されます Set@bloc2@bloc4@bloc5@bloc6 — ブロック 2 / 4 / 5 / 6 の値が受信したデータに置き換えられます Caché 側には [Arduino.Delegate](https://github.com/intersystems-ru/ArduinoSnippets/blob/master/Arduino/Delegated.cls.xml) クラスがあり、その中に次の 2 つの対応するエントリポイントがあります。 * SetCredentials — ユーザー名とパスワードの入力を取得し、それをシステムに格納されているキーを使用して AES 暗号化で暗号化し、RFID カードに書き込みます。 GetCredentials — カードから暗号化テキストを受信して復号化し、ユーザー名、パスワード、および操作のステータスを返します。 また、GetCredentials を使用して Arduino.Delegated クラスを呼び出す ZAUTHENTICATE ルーチンは以下のとおりです。 ZAUTHENTICATE(ServiceName, Namespace, Username, Password, Credentials, Properties) PUBLIC { #Include %occStatus Quit $$$OK } GetCredentials(ServiceName, Namespace, Username, Password, Credentials) Public { #Include %occErrors #Include %occStatus Quit ##class(Arduino.Delegated).GetCredentials(.Username, .Password) } これで準備完了です! 組み立て後のデバイスは次のようになります。 ![](/sites/default/files/inline/images/8f7b06a6e43640d99569c80c3e0496fb.jpg) 次のようにターミナルでシステム暗号化キーを設定します(%SYS ネームスペースと Arduino.Delegated クラスを使用できる必要があります)。 Do ##class(Arduino.Delegated).InitEncryption(Key, IV) ここで、Key は暗号化キー、IV は初期化ベクトルです。 これらは、ユーザー名とパスワードを暗号化するために使用されます。 コマンドを使用して認証するには、Arduino を Caché に接続し、カードに情報を書き込みます。 Do ##class(Arduino.Delegated).SetCredentials("_SYSTEM", "SYS") 適切なサービスまたは Web アプリケーション(端末やシステム管理ポータルなど)で委任認証とパスワード認証を有効にすると、カードを RFID カードリーダーにかざすことで認証できるようになります。 考えられる機能強化 * [マネージド暗号化キー](http://docs.intersystems.com/cache20161/csp/docbook/DocBook.UI.Page.cls?KEY=GCAS_encrypt#GCAS_encrypt_mgmt)を使用してユーザー名とパスワードを暗号化すると、セキュリティを強化できます。 * 2 要素認証を使用すると、セキュリティを強化できます。具体的には、先にユーザー名とパスワードのペアを取得してから、ユーザーに固有のキーが格納されているカードを読み取ります。 次に、受信したキーをシステムに格納されている特定ユーザーのキーで確認する必要があります。 任意のユーザーデータを格納する方法は、InterSystems のコミュニティで[議論されています](https://community.intersystems.com/post/best-practices-store-user-informationsettings-cach%C3%A9)。 それぞれ 15 文字を超えるユーザー名とパスワードを格納する機能を追加します。 まとめ 柔軟性の高い Caché の認証システムを使えば、任意のユーザー認証ロジックを実装できます。 リンク * [ドキュメント](http://docs.intersystems.com/cache20161/csp/docbook/DocBook.UI.Page.cls?KEY=GCAS_delegated) * [GitHub リポジトリ](https://github.com/intersystems-ru/ArduinoSnippets) * SAMPLES ネームスペースには ZAUTHENTICATE ルーチンの例も含まれています
記事
Toshihiko Minamoto · 2020年11月18日

クラス、テーブル、グローバルとその仕組み

クラス、テーブル、グローバルとその仕組み InterSystems IRIS を技術的知識を持つ人々に説明する際、私はいつもコアとしてマルチモデル DBMSであることから始めます。 個人的には、それが(DBMSとして)メインの長所であると考えています。 また、データが格納されるのは一度だけです。 ユーザーは単に使用するアクセス API を選択するだけです。 - データのサマリをソートしたいですか?SQL を使用してください! - 1 つのレコードを手広く操作したいですか?オブジェクトを使用してください! - あなたが知っているキーに対して、1 つの値にアクセスしたりセットしたいですか? グローバルを使用してください! これは短く簡潔なメッセージで、一見すると素晴らしく聞こえます。しかし、実際には intersystems IRIS を使い始めるたユーザーには クラス、テーブル、グローバルはそれぞれどのように関連しているのだろうか? 互いにどのような存在なのだろうか? データは実際にどのように格納されているのだろうか?といった疑問が生じます。 この記事では、これらの疑問に答えながら実際の動きを説明するつもりです。 ## パート 1. モデルに対する偏見。 データを処理するユーザーは多くの場合、処理対象のモデルに偏見を持っています。 開発者はオブジェクトで考えます。 このようなユーザーにとって、データベースとテーブルは CRUD(Create-Read-Update-Delete、ORM の使用が望ましい)を介して操作する箱のようなものですが、その基礎となる概念モデルはオブジェクトです(これは主に私たちのような多くのオブジェクト指向言語の開発者に当てはまります)。 一方、リレーショナル DBMS に多くの時間を費やしているデータベース管理者は往々にしてデータをテーブルと見なしています。 この場合、オブジェクトはレコードの単なるラッパー扱いです。 また、InterSystems IRIS では永続クラスはデータをグローバルに格納するテーブルでもあるため、いくつかの説明が必要になります。 ## パート 2. 具体例 次のような Point クラスを作成したとします。 ```objectscript Class try.Point Extends %Persistent [DDLAllowed] { Property X; Property Y; } ``` 次のように DDL/SQL を使用して同じクラスを作成することもできます。 ``` CREATE Table try.Point ( X VARCHAR(50), Y VARCHAR(50)) ``` コンパイル後、新しいクラスがグローバルにネイティブに格納されているデータをカラム(またはオブジェクト指向のユーザーの場合はプロパティ)にマッピングするストレージ構造を自動生成します。 ``` Storage Default { %%CLASSNAME X Y ^try.PointD PointDefaultData ^try.PointD ^try.PointI ^try.PointS %Library.CacheStorage } ``` ここでは何が起きているのでしょうか? 下から順番に説明します(**太字**の単語が重要です。残りは無視してください)。 - Type - 生成されたストレージタイプ。この場合は永続オブジェクトのデフォルトストレージです。 - StreamLocation - ストリームを格納するグローバルです。 - IndexLocation - インデックス用のグローバルです。 - IdLocation - ID の自動インクリメントカウンターを格納するグローバルです。 - **DefaultData** - グローバルの値をカラム/プロパティにマッピングするストレージの XML 要素です。 - **DataLocation** - データを格納するグローバルです。 ここでは「DefaultData」が `PointDefaultData` となっていますので、その構造をもう少し詳しく見てみましょう。 基本的に、グローバルノードは次の構造を持っていると言われています。 - 1 - %%CLASSNAME - 2 - X - 3 - Y したがって、グローバルは次のようになると予想されます。 ``` ^try.PointD(id) = %%CLASSNAME, X, Y ``` しかし、グローバルを出力すると空になります。ここではデータを追加していなかったためです。 ``` zw ^try.PointD ``` オブジェクトを 1 つ追加しましょう。 ``` set p = ##class(try.Point).%New() set p.X = 1 set p.Y = 2 write p.%Save() ``` すると、グローバルはこのようになります。 ``` zw ^try.PointD ^try.PointD=1 ^try.PointD(1)=$lb("",1,2) ``` ご覧のように、期待する構造 %%CLASSNAME, X, Y はオブジェクトの X プロパティと Y プロパティに対応する `$lb("",1,2)` とセットになっています(%%CLASSNAME はシステムプロパティですので無視してください)。 次のように SQL を使用してレコードを追加することもできます。 ``` INSERT INTO try.Point (X, Y) VALUES (3,4) ``` すると、グローバルの内容は次のようになります。 ``` zw ^try.PointD ^try.PointD=2 ^try.PointD(1)=$lb("",1,2) ^try.PointD(2)=$lb("",3,4) ``` つまり、オブジェクトまたは SQL を介して追加するデータは、ストレージ定義に従ってグローバルに格納されます(補足:PointDefaultData の X と Y を置き換えることでストレージ定義を手動で変更できます。その場合に新しいデータがどうなるかを確認してください!)。 では、SQL クエリを実行したい場合はどうなるのでしょうか? ``` SELECT * FROM try.Point ``` これは `^try.PointD` グローバルを反復処理し、ストレージ定義(正確にはその `PointDefaultData` 部分)に基づいてカラムにデータを入力する ObjectScript コードに変換されます。 今度は変更を行います。 テーブルからすべてのデータを削除しましょう。 ``` DELETE FROM try.Point ``` すると、この時点でグローバルの内容は次のようになります。 ``` zw ^try.PointD ^try.PointD=2 ``` ここでは ID カウンターのみが残っているため、新しいオブジェクト/レコードの ID は 3 になることに注意してください。 また、クラスとテーブルは引き続き存在します。 しかし、次を実行するとどうなるでしょうか。 ``` DROP TABLE try.Point ``` これはテーブルとクラスを破棄し、グローバルを削除します。 ``` zw ^try.PointD ``` 皆さんがこの具体例に従い、グローバル、クラス、テーブルがどのように統合され、相互に補完しているかをより深く理解できたことを願っています。 手元の仕事に適切な API を使用すれば、開発がより高速かつアジャイルになり、バグが少なくなります。
記事
Toshihiko Minamoto · 2022年12月21日

Django 入門 パート 3

Django の可能性と IRIS の使用方法を引き続き観察しています。 [初めに](https://jp.community.intersystems.com/node/527776)モデルの定義方法と、IRIS に存在しているテーブルへの接続方法を確認し、[次に](https://jp.community.intersystems.com/node/527781)組み込みの Django 管理ポータルを拡張して、モデルに含まれるデータの表示、フィルタ、編集、そしてページネーションの機能を追加しました。 では、実際の動作を確認しましょう。posts-and-tags パッケージで使用したデータで Django に REST API を作成します。 それには、[Django REST Framework](https://www.django-rest-framework.org/) を使用します。 ![Django REST Framework](https://www.django-rest-framework.org/img/logo.png) Django REST Framework は、Web API を構築するための強力で柔軟性を備えたツールキットです。 REST Framework の使用を推奨するのには、以下のような理由があります。 * Web で閲覧可能な API には、開発者のユーザビリティにおいて大きなメリットがあります。 * OAuth1a と OAuth2 の認証ポリシーを含むパッケージ * ORM と非 ORM データソースの両方をサポートするシリアル化 * すべてをカスタマイズ可能。強力な機能が必要なければ、通常の関数ベースのビューを使用できます。 * 詳細なドキュメントと優れたコミュニティサポート * Mozilla、Red Hat、Heroku、Eventbrite など、世界的に有名な企業が使用・信頼 まず、依存関係で requirements.txt を更新する必要があります。 # Django そのもの django>=4.0.0 # Django 用 InterSystems IRIS ドライバー、InterSystems の DB-API ドライバー django-iris=>0.1.13 https://raw.githubusercontent.com/intersystems-community/iris-driver-distribution/main/DB-API/intersystems_irispython-3.2.0-py3-none-any.whl # Django REST Framework とそのオプションの依存関係 djangorestframework>=3.4.4 # 閲覧可能な API の Markdown サポート markdown>=3.0.0 # フィルタサポート django-filter>=1.0.1 そして、これらをインストールします。 python install -r requirements.txt ## API の初稿 _urls.py_ ファイルを以下に更新します。 ここでは、API のルートを **_api/_** に更新し、API リクエストに対し、http://localhost:8000/api/ がルートとして使用されるようにします。 from django.contrib import admin from django.urls import path, include from rest_framework import routers router = routers.DefaultRouter() urlpatterns = [ path('api/', include(router.urls)), path('admin/', admin.site.urls), path('api-auth/', include('rest_framework.urls')), ] Django REST Framework には、settings.py の DEBUG=True によりサーバーが開発モードで実行している場合、API の UI が組み込まれています。 この URL を開きましょう。 ![](/sites/default/files/inline/images/images/image(4289).png) 何も定義されておらず、フレームワークが URL に接続されているだけでも、すべてが機能しています。 認証を必要とするリクエストに対しては、認証がサポートされています。  $ curl http://127.0.0.1:8000/api/ {} プロジェクトの API を定義しましょう。最低限、REST Framework のいくつかの機能を使用します。 * シリアライザー - クエリセットやモデルインスタンスなどの複雑なデータをネイティブ Python データ型に変換し、`JSON` や `XML` などのコンテンツタイプに簡単にレンダリングできるようにします。 シリアライザーは逆シリアル化も提供しているため、着信データを検証してから、解析したデータを複雑な型に変換し直すことも可能です。 * ビューセット - 関連する一連のビューのロジックを 1 つのクラスにまとめることができます。 Post 用のエンドポイントを追加しましょう。 とてもシンプルではありますが、 更新された **_urls.py _** のコンテンツを見てみましょう。 from django.contrib import admin from django.urls import path, include from rest_framework import routers, serializers, viewsets from .models import CommunityPost router = routers.DefaultRouter() class CommunityPostSerializer(serializers.HyperlinkedModelSerializer): class Meta: # class with model model = CommunityPost # list of fields to show, or just '__all__' fields = '__all__' # ViewSets define the view behavior. class CommunityPostViewSet(viewsets.ModelViewSet): queryset = CommunityPost.objects.all() serializer_class = CommunityPostSerializer # connect it with API router.register(r'posts', CommunityPostViewSet) urlpatterns = [ path('api/', include(router.urls)), path('admin/', admin.site.urls), path('api-auth/', include('rest_framework.urls')), ] これで Web UI に表示されるようになりました。 ![](/sites/default/files/inline/images/images/image(4290).png) ここのリンクをクリックすると、そのレスポンスを確認できます。 ![](/sites/default/files/inline/images/images/image(4291).png) 最後までスクロールすると、新しい項目用に生成されたフォームがあります。これは POST リクエストで追加可能です。 すべてのフィールドがプロパティの型に適しています。 ![](/sites/default/files/inline/images/images/image(4292).png) 項目リストで任意の項目の URL をクリックして、これを確認します。 レスポンスのこの項目と、PUT リクエストを使った編集フォームのみです。 ![](/sites/default/files/inline/images/images/image(4294).png) ## 認証 PUT か POST でデータを変更できるようになりました。 認証の要件はまだ有効化されていません。 REST Framework には、使用できる認証の組み合わせが様々用意されているため、匿名アクセスの読み取り専用リソースを一部開放することができます。 そして、変更を行うための認証を行います。 または、アクセスを完全に閉鎖することも可能です。 ここでは、匿名の読み取り専用に構成し、変更には認証を必要とするようにしましょう。 それには、次のコードを **_settings.py_** に追加すれば完了です。 REST_FRAMEWORK = { # Use Django’s standard `django.contrib.auth` permissions, # or allow read-only access for unauthenticated users. 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly', ], } これを使用すれば、Django 管理用に前に作成したユーザー名とパスワードなどでログインするまで、フォームが表示されなくなります。 ## ページネーション デフォルトではページネーションはありませんが、リストクエリに簡単に追加できます。 **_settings.py_** の **REST_FRAMEWORK** 変数を更新しましょう。 ページネーションクラスとデフォルトのページサイズをセットアップします。 REST_FRAMEWORK = { ... 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination', 'PAGE_SIZE': 10, ... } これにより、生成される JSON がわずかに変わりました。「次へ」や「前へ」といったページリンクや全項目数などの関連する項目が追加されています。 これで、Web UI でページを移動できるようになりました。 ![](/sites/default/files/inline/images/images/ezgif_com-gif-maker_(4).gif) ## フィルタと検索 フィルタ機能と検索機能の追加も非常に単純です。 **_settings.py_** の **REST_FRAMEWORK** 変数を更新しましょう。  REST_FRAMEWORK = { ... 'DEFAULT_FILTER_BACKENDS': [ 'django_filters.rest_framework.DjangoFilterBackend', 'rest_framework.filters.SearchFilter', ], ... ] そして、CommunityPostViewSet をフィルタと検索用のフィールドのリストで更新します。 class CommunityPostViewSet(viewsets.ModelViewSet): queryset = CommunityPost.objects.all() serializer_class = CommunityPostSerializer filterset_fields = ['posttype', 'lang', 'published'] search_fields = ['name',] これで、Web UI で動作するようになりました。 ![](/sites/default/files/inline/images/images/ezgif_com-gif-maker_(5).gif) 最後に、完全に機能する REST API が完成しましたが、今のところ、このリソース専用の API です。 非常に単純ですが、十分にカスタマイズ可能で、他のリソースに接続したり、リンクしたリすることが可能です。
記事
Toshihiko Minamoto · 2020年11月18日

FTP ファイルのダウンロード(すべてのファイル、ファイル数)オプション: ファイルのコピーまたはファイルの移動

FTP ファイルを Intersystems Caché からダウンロードする**メソッド**を以下に示します。ご質問がある場合はメッセージをお寄せください。 ClassMethod FTPDownload(myFTP = "", myUserName = "", myPassword = "", sFileLocation = "", dLocation = "", noOfdownloadFile = 1, sourceFileDel = ){ /*---------------------------------------------------------------------------------------------------------------------------  要件に従ってファイルをダウンロードします  : FTP メソッド : 再利用可能  作成者 : Sanjib Raj Pandey、30/03/2018 に作成  downLoadFile = ファイル数またはすべてのファイル  ...... ダウンロードしたいファイルを指定します、デフォルト値は 1 です。   = 1,3,7,100 ファイルなどの値を指定します。   = すべてのファイルをダウンロードするには "*" を指定します。   SourceFileDel = ダウンロード後にソースフォルダーのファイルを削除したい場合は.....                   この値を 1 に設定します  -- ;   デフォルト値 :  0                   1= True (ダウンロード後にソースフォルダーを削除する)、 0 = False(コピーのみ)   sFileLocation = ソースファイルの場所(フォルダー)  dLocation = 宛先フォルダー例 :  以下の内容は ..... すべてのファイルをソースから宛先フォルダーに移動します。  w ##class(CW.COMMON).FTPDownload("IP アドレス","ユーザー名","パスワード","ソースフォルダー","宛先フォルダー,"*",1) 以下の内容は...... 200 ファイルをソースから宛先フォルダーにコピーします。w ##class(CW.COMMON).FTPDownload("IP アドレス","ユーザー名","パスワード","ソースフォルダー","宛先フォルダー,200,0)   ------------------------------------------------------------------------------------------------------------------------- */ // Try .. Catch のようなエラー制御をセットアップできます。   Set (count,fileNo,key,messge,fileStream,myFileName,myFile,fSave,eMessage,eSubject)="" Set fIp= myFTP  Set fUserName= myUserName  set fPassword=myPassword  set sFileLocaion=sFileLocation  set dLocation=dLocation  Set downloadFile=noOfdownloadFile  Set sourceFileDel=sourceFileDel  If $Length(fIp)=0||($L(fUserName)=0)||($L(fPassword)=0) || ($L(downloadFile)=0) Q "資格情報が無効であるか、ダウンロードファイルが 0 です!IP、ユーザー名、パスワード、FTP または宛先の場所を確認してください!"       Set myFtp=##class(%Net.FtpSession).%New() Set eMessage="FTP 接続に失敗しました。"_fIp_" またはユーザー名、パスワードをチェックしてください!" Set eSubject ="FTP 警告メッセージ。"   Set myFtp.Timeout = 60 If 'myFtp.Connect(fIp,fUserName,fPassword) Quit  w $$EVEMAIL^CW.COMMON(eSubject,eMessage) Do myFtp.SetDirectory(sFileLocaion) If 'myFtp.NameList(" ",.x) Quit "ファイルが見つかりません " Set fileStream = ##class(%Stream.FileBinary).%New() Set message ="コピー" Set myFileName="" Set fileNo=0 Set Key="" If (downloadFile = "*") {   While (x.GetNext(.Key))'="" {       Do StartCopy }Do myFtp.Logout()Quit fileNo_" ファイルが正常に"_message_"されました!"    }  If (downloadFile >0) {       Set count=1        While ((count 
記事
Mihoko Iijima · 2020年12月15日

IIS で REST を動かす場合の設定

これはInterSystems FAQ サイトの記事です。 REST のベース URL を /rest とした場合の IIS と Webゲートウェイの設定内容は以下の通りです。 IIS の設定内容 アプリケーション /rest を作成し、ハンドラーマッピングで * = CSPms を定義します。 ハンドラーマッピングの設定手順は以下の通りです。 IIS > Default Website > アプリケーション /rest > "ハンドラーマッピング" をダブルクリック > モジュールマップの追加 要求パス : * モジュール: CSPms 名前   : CSPGW (任意の名前) 要求の制限 > [要求のマップ先が次の場合のみハンドラーを呼び出す] のチェックはオフにします。※こちらの設定はデフォルトでは「チェックあり」になっていますのでご注意ください。 この構成により、IIS は /rest アプリケーションを Web ゲートウェイに転送します。 Webゲートウェイの構成 Web Gateway のアプリケーションアクセス から /rest を追加します。→既存アプリケーションをクリックしてコピーし、アプリケーションパスを /rest に設定しIRISサーバを指定します。 この構成により、Webゲートウェイは /rest アプリケーションをIRISサーバに転送します。 IRISサーバの構成 管理ポータルを開き、システム構成 > セキュリティ > アプリケーション > ウェブ・アプリケーション より /rest アプリケーションを追加します。 RESTディスパッチクラス名を「ディスパッチクラス」に指定します。 この構成により、IRIS は /rest アプリケーションを対象ネームスペースに転送し、対象ディスパッチクラスを呼び出します。 IIS経由でテスト 以下のURLで呼び出します。 http://localhost/rest/test REST ディスパッチクラスが以下のようなサンプルコードだった場合 Class User.MyREST Extends %CSP.REST { XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ] { <Routes> <Route Url="/test" Method="GET" Call="test"/> </Routes> } ClassMethod test() As %Status { set %response.ContentType="application/json" set res={"abc":"123"} write res.%ToJSON() quit $$$OK } } 以下の結果が得られます。
記事
Mihoko Iijima · 2021年3月9日

ダイナミックオブジェクトの JSON 変換で MAXSTRING エラーが出る場合の対処方法

これは InterSystems FAQ サイトの記事です。 ダイナミックオブジェクトから JSON 文字列を生成するときに使用する %ToJSON() の引数にストリームオブジェクトを指定することでエラーを回避できます。 コード例は以下の通りです。 USER>set temp=##class(%Stream.TmpCharacter).%New() USER>set jsonobj={} USER>set jsonobj.pro1=["a","b","c","d"] USER>set jsonobj.pro2=["あ","い","う","え"] USER>do jsonobj.%ToJSON(temp) USER>write temp.Size 51 USER>write temp.Read() {"pro1":["a","b","c","d"],"pro2":["あ","い","う","え"]} 詳細はドキュメントもご参照下さい。 【IRIS】大きいダイナミック・エンティティからストリームへのシリアル化 大きいダイナミック・エンティティからストリームへのシリアル化 こんにちは、mihokoさん %Stream.TmpCharacterクラスを使用した場合、IRISTEMPデータベースにデータが書き込まれると理解してよろしいでしょうか? また、作成したストリームデータは明示的に削除する必要はありますか? こんにちは、Amanoさん ご質問ありがとうございます! 確認してみたところ、ご質問いただいたように、IRISTEMP に書くには書くのですが、大きなサイズになったときにプロセスプライベートグローバル(=PPG。こちらも IRISTEMP に格納される変数)へセットしていました。 ちなみに、上に書いているサンプルだと、PPG は使用していませんでした。 削除についてですが、ストリームを格納した変数を消去すると使用していた PPG も消えますので、「ストリームをセットした変数を kill する」を入れるのが確実だと思います(メソッド終了でローカル変数も消えますが、明示的に書いた方がわかりやすいかな、と思いました)。 確認するまで私も知りませんでしたので、ご質問いただきありがとうございました! mihokoさん %Stream.TmpCharacterクラスは便利そうですね。 回答ありがとうございました。
記事
Mihoko Iijima · 2021年3月9日

アプリケーションエラー(^ERRORS)をコマンドで取得する方法

これは InterSystems FAQ サイトの記事です。 SYS.ApplicationError クラスの ErrorList クエリを使用します。 注意1:%SYS ネームスペースで実行します。 注意2:ストアド化していないユーティリティのため %SQL.Statement ではなく %ResultSet クラスを利用します。 コマンド実行例は以下の通りです。 USER>set $namespace="%SYS" //または zn "%SYS" %SYS>set rset=##class(%ResultSet).%New() %SYS>set rset.ClassName="SYS.ApplicationError" %SYS>set rset.QueryName="ErrorList" // クエリの第1引数はネームスペース名、第2引数は日付を指定します(形式:MM/DD/YYYY) %SYS>do rset.Execute("USER","08/17/2020") // 画面に結果を表示させる場合は %Display()メソッドを実行します。 %SYS>do rset.%Display() Error # Error message Time Process DisplayPID Username Code line 1 <DIVIDE> 02:43:10 2536 2536 irisowner 1 Rows(s) Affected %SYS>do rset.Close() 行移動しながら、SELECT の 列の値を取得する方法は以下の通りです。 行移動には Next() メソッドを使用します(行が存在すると 1 を返します)。 列の取得には Get("列名") を使用します。列名詳細については、クラスドキュメントから ErrorList クエリの説明文をご参照ください。ErrorListクエリの列名について %SYS>do rset.Execute("USER","08/17/2020") %SYS>while rset.Next() { write rset.Get("Error #"),"-",rset.Get("Error message"),"-",rset.Get("Time"),"-",rset.Get("Code line"),!} 1-<DIVIDE>-02:43:10- ターミナルで表示する場合は、^%ER ルーチンも利用できます。 参照したいネームスペースに移動した状態で以下実行します(例は USER ネームスペースで実行しています)。下線付き緑色の太字は入力箇所です。 USER>do ^%ER For Date: ?L Thu 09/17/2020 (T) 2 Errors Mon 09/07/2020 (T-10) 3 Errors Mon 08/31/2020 (T-17) 1 Error Mon 08/24/2020 (T-24) 1 Error For Date: 09/17/2020 17 Sep 2020 2 Errors Error: ?L 1. " *a" at 9:05 am. $I=|TRM|:|13484 ($X=0 $Y=15) $J=13484 $ZA=0 $ZB=$c(13) $ZS=262144 ($S=268271680) 2. "^%ETN" at 9:05 am. $I=|TRM|:|13484 ($X=0 $Y=17) $J=13484 $ZA=0 $ZB=$c(13) $ZS=262144 ($S=268263368) %ETN ;%STACK-related error log Error: 1 1. " *a" at 9:05 am. $I=|TRM|:|13484 ($X=0 $Y=15) $J=13484 $ZA=0 $ZB=$c(13) $ZS=262144 ($S=268271680) Variable: Error: For Date: USER> For Date: には発生したエラー日を mm/dd/yyyy の形式で指定します。 Error: には、エラー番号を指定します。 表示を終了したい場合は、Enter を押して終了します。
記事
Hiroshi Sato · 2021年9月23日

タスクスケジュールを別環境にコピーする方法

これは InterSystems FAQ サイトの記事です。 タスクスケジュールを別環境にコピー(エクスポート/インポート)するには、以下の2つの方法があります。 個別にエクスポート/インポートする場合(管理ポータルで行う方法) 複数のタスクスケジュールをエクスポート/インポートする場合(%SYS.TaskSuperクラスを使用する方法) 1.個別にエクスポート/インポートする場合 管理ポータルから行うことが可能です。 個別のスケジュールを開くと、エクスポートボタンがあるので、そちらからエクスポートしてください。 インポートも同じく管理ポータルから行えます。 2.複数のタスクスケジュールをエクスポート/インポートする場合 タスクスケジュールのエクスポートには、%SYS.TaskSuper クラスの ExportTasks() メソッドをお使いいただけます。 実行例は以下のようになります。 %SYS>do ##class("%SYS.TaskSuper").ExportTasks($lb(1,2,3,4,5),"c:\temp\exportedTasks.xml") エクスポートするタスクID を $LB形式で指定します。複数指定する場合は、$lb(1,2,3,4,5) のようにカンマ区切りで指定します。 タスクIDはシステム管理ポータルシステムオペレーション > タスクマネージャ > タスクスケジュールのIDカラムになります。 インポートは以下のように行います。 USER>do ##class(%SYS.TaskSuper).ImportTasks("c:\temp\exportedTasks.xml")TEST imported. 尚、インポートは管理ポータルから行うことも可能です。 タスクマネージャの電子メール設定は、インポートでは移行できませんので、タスクのインポートが完了したら、ターゲット・サーバでタスク・マネージャの電子メール設定を構成する必要があります。 管理ポータルで、[システム管理] > [構成] > [追加設定] > [タスクマネージャEメール]に移動して、これを行うことができます。 ソースサーバの同じ画面から各フィールドをコピーして貼り付けます。
記事
Hiroshi Sato · 2021年9月17日

スタジオ、ターミナル、管理ポータルのライセンス消費ユーザをまとめる方法

これは InterSystems FAQ サイトの記事です。※ IRIS Data Platformのサーバーライセンス(プロセッサーコア単位の課金)では以下の内容は適用されませんので、ご注意お願いします。 2012.1以降のバージョンより、ライセンス管理が厳格化されたために、管理ポータルでもライセンスを消費するようになりました。 デフォルトでは、管理ポータルは独立したID(CSPセッション)単位でライセンスを消費するために同一ユーザが複数ライセンスを消費するようになります。 スタジオ、ターミナル、管理ポータル全ての消費ライセンスをに同一ユーザにまとめる方法は以下になります。 (1) スタジオ、ターミナル、管理ポータルに共通ユーザでログイン 管理ポータル: [システム管理] > [セキュリティ] > [サービス] 以下3つを「パスワード」認証のみに変更 %Service_Bindings%Service_Telnet%Service_Console 管理ポータル: [システム管理] > [セキュリティ] > [アプリケーション] > [ウェブ・アプリケーション] 以下6つを「パスワード」認証のみに変更 /csp/sys/csp/sys/bi/csp/sys/exp/csp/sys/mgr/csp/sys/op/csp/sys/sec (2) %ZSTARTルーチンのSYSTEMラベルを作成し以下を実行 SYSTEM set dummy=$SYSTEM.License.UserNameLicensing(1) quit ターミナルから set dummy=$SYSTEM.License.UserNameLicensing(1) を実行すると、ライセンスは <ユーザ名@IP> でまとまります。 (1)のあとに、上記コマンドを実行することで、次のログインより消費ライセンスを同一ユーザにまとめることが可能になります。 ただし、こちらの設定はインスタンスを停止するまで有効ですが、再起動するとクリアされてしまいます。 再起動ごとにコマンドを実行する手間を省くためには、(2)の SYSTEM^%ZSTART にて実行する方法を使用します。 ※この設定は管理ポータルで行うことはできません。 詳細については、以下ドキュメントをご参照ください。 ライセンスの消費を<ユーザ名@IP>に変更する方法について【IRIS】 ライセンスの消費を<ユーザ名@IP>に変更する方法について
記事
Megumi Kakechi · 2021年6月30日

管理ポータルのライセンス消費に関する仕様変更について(2012.1以降)

これは InterSystems FAQ サイトの記事です。 2012.1以降管理ポータルの使用もライセンスを消費する様にシステムを変更しました。 これはインターシステムズが定める製品のライセンスポリシーとシステムの動作をできるだけ合わせる一連の措置の1つとして行われました。 この変更に伴いライセンス使用に関わる思わぬトラブルが発生する可能性がありますので注意が必要です。 特にライセンスの解放が管理ポータルページの操作法によって異なるため、その違いを十分認識して対処する必要があります。 管理ポータルのライセンスの解放はページの切断の仕方により以下の様に変わります。 a) ポータルを開き何らかの操作を行った後にログアウトを行うとライセンスは即時解放されます。 b) ポータルのページを開いた後、他に何も操作せずにログアウトを行うと一定の待ち時間の後にライセンスの解放が行われます。 この待ち時間はライセンスの意図的な規約違反を防ぐための措置であるため、設定等で変更できないようになっています。 c) ポータルを開き、ブラウザのXボタンやAlt+F4等のショートカットでページを強制的に閉じた場合は、デフォルトでは8時間後にライセンスの解放が行われます。 ライセンスの解放の時間は以下の操作で変更することができます。 管理ポータル: [システム管理] > [セキュリティ] > [アプリケーション] > [ウェブ・アプリケーション] で /csp/sys/ 以下の全てのアプリケーションを編集してセッションタイムアウトをデフォルトの 28800 秒から変更します。 また、以下のドキュメントもあわせてご参照ください。 CSP ライセンス使用
記事
Megumi Kakechi · 2021年9月3日

文字列の中から数値だけを抜き出す方法

これは InterSystems FAQ サイトの記事です。 $ZSTRIPコマンドは、指定された文字列から文字のタイプと文字を削除します。このコマンドを使用することで文字列から数値部分のみを抽出することが可能です。 $ZSTRIP(string,action,remchar,keepchar) 第1引数(string) :対象文字列第2引数(action) :string から削除する対象。アクションコードとマスクコードで構成。第3引数(remchar) :削除する特定の文字を指定。第2引数のマスクコードに含まれない文字も指定可能。【オプション】第4引数(keepchar):削除しない特定の文字を指定。【オプション】 以下はその例です。 // 第2引数:アクションコード "*" を指定しすべて削除(E)// 第4引数:.0123456789- を削除しないUSER>write $zstrip("ABC-0.100g","*E",,".0123456789-")-0.100 ★マスクコード---------------------------------------------------- E すべてを削除しますA すべてのアルファベット文字を削除しますP 空白スペースと、句読記号文字を削除しますC 制御文字 (0-31、127-159) を削除しますN 数字を削除しますL アルファベットの小文字を削除しますU アルファベットの大文字を削除しますW 空白を削除します ($C(9)、$C(32)、$C(160))---------------------------------------------------- ★アクションコード---------------------------------------------------- * マスク・コード (複数可) に一致するすべての文字を削除します< マスク・コード (複数可) に一致する先頭の文字を削除します> マスク・コード (複数可) に一致する末尾の文字を削除します<> マスク・コード (複数可) に一致する先頭および末尾の文字を削除します= マスク・コード (複数可) に一致する繰り返し文字を削除します<=> マスク・コード (複数可) に一致する先頭、末尾、および繰り返し文字を削除します---------------------------------------------------- $ZSTRIPの詳しい使用方法については、以下のドキュメントをご覧ください。$ZSTRIPについて 以下の関連トピックもあわせてご覧ください。文字列の前後の半角スペース及び全角スペースを取り除く方法
記事
Tomohiro Iwamoto · 2022年7月11日

oAuth2認証対応のIMAP,SMTPアダプタ

オリジナルの[「InterSystems IRIS で Python を使って IMAPクライアントを実装する」](https://jp.community.intersystems.com/node/512311)は、埋め込みPythonを使用してIMAPインバウンドアダプタを実装されていますが、最近メールプロバイダがあいついでoAuth2認証しか受け付けなくなってきているので、その対応をしてみました。 本稿の[GitHub](https://github.com/IRISMeister/iris-imap-inbound-adapter-demo.git)はこちらです。 # 変更点 GMAILに対してメールの送受信を可能とするためにオリジナルに以下の修正を施しています。 1. IMAP(Python版)インバウンドアダプタにoAuth2認証およびRefreshTokenによるAccessTokenの更新を追加 2. oAuth2認証およびRefreshTokenによるAccessTokenの更新機能を持つSMTPアウトバウンドアダプタを新規作成 3. IMAPにバイナリの添付ファイルの処理を追加 4. メッセージ削除に、推奨APIであるclient.uid("STORE")を使用するように変更 5. ClientIdなど、センシティブな情報をコンテナ起動時に動的に適用するように変更 6. 日本語使用時の文字化けに対処 > 3.添付ファイルが存在する場合、追加設定/ファイル・パスで指定したファイルパス(既定値は/var/tmp/)上に保存します。 > 5.の実現は、プロダクション([IMAPPyProduction.cls](src/dc/demo/imap/python/IMAPPyProduction.cls))起動の際に実行されるコールバックOnStart()で、準備したjsonファイルの取り込みを行っています。 > zpmパッケージの内容はオリジナルのままです。 # 事前準備 実行には、以下のパラメータの準備が必要です。 |パラメータ|取得方法| |:---|:---| |GMAILアカウント|認証対象となるGMAILアカウント。xxxx@gmail.com等| |ClientID|GCPで発行されるclient_id| |ClientSecret|GCPで発行されるclient_secret| |TokenEndPoint|GCPで発行されるtoken_uri| |RefreshToken|下記のoauth2.py等を使用して取得| これらの値を[gmail_client_secret.template](gmail_client_secret.template)を参考に、gmail_client_secret.jsonに設定してください。 ClientID, ClientSecret, TokenEndPointは、GCPのコンソールで、デスクトップクライアント用にoAuth2を発行した際にダウンロードできるJSONファイルから取得すると便利です。 ``` $ cat client_secret_xxxxxx.apps.googleusercontent.com.json | jq { "installed": { "client_id": "xxxxx.apps.googleusercontent.com",
記事
Megumi Kakechi · 2022年10月26日

IRIS が起動時に必要とするポート

これは InterSystems FAQ サイトの記事です。 IRISが起動時に必要とするポートは、次のとおりです。(ポート番号はデフォルト設定の場合です。)1. 1972 : IRIS のスーパーサーバポート(管理ポータルで変更可能) IRIS 起動のために、必須のポートです。 このポートが使用できないと IRIS は正常に起動しません。 ※IRIS 2019.2以前のバージョンでは、スーパーサーバーポートは 51773 でした。 2. 4002 : IRIS ライセンスサーバポート(管理ポータルで変更可能) IRIS がライセンスサーバになる場合、必要なポートです。 このポートが使用できないと、正しいライセンス情報が取得できません。 ライセンスクライアントについては、このポートは必須ではありません。 ※リモートライセンスサーバがファイアウォールで保護されている場合、UDP トラフィックに対してライセンスサーバポートが開かれている必要があります。   ライセンスサーバの構成について 3. 23 :IRIS Telnetポート(管理ポータルで変更可能) IRIS サーバが Windows で、かつ、クライアントから IRIS ターミナルによる操作を行う場合にのみ、必要なポートです。 4. 52773 : 管理用Webサーバポート(管理ポータルで変更可能) IRIS 管理ポータル用に自動起動する、Webサーバポートです。 ※ユーザアプリで使用する場合は、 ApacheやIISなどのウェブサーバで使用されるポート 80 (既定)となります。 5. 2188 : ISCAgentポート(管理ポータルで変更可能) ミラーリングを使用するときにのみ、必要なポートです。 IRIS のスーパーサーバポートについては、IANAのPort番号一覧で明記されております(Cacheでの登録になります)。 intersys-cache 1972/tcp Cacheintersys-cache 1972/udp Cache 以下ページをご参照ください。 iana.orgのページ ※2.IRIS ライセンスサーバポート を修正しました(修正前:4001、修正後:4002)IRISでは、ライセンスサーバの既定のポート番号は「4002」になります。Cacheの場合は「4001」でした。
記事
Megumi Kakechi · 2023年2月2日

並列クエリについて(%PARALLEL)

これは InterSystems FAQ サイトの記事です。 クエリパフォーマンスを最適化するための方法の一つとして、クエリ単位またはシステム全体でクエリの並列処理を使用することができます(標準機能)。 こちらは、特定のクエリに対しマルチプロセッサシステムでクエリの実行をプロセッサ間で分割して行うものです。並列処理の効果が得られる可能性がある場合のみ、クエリオプティマイザは並列処理を実行します。並列処理の対象はSELECT文のみとなります。 なお、並列プロセスの数は、CPUの数に応じて自動で調整するため、数の指定は行えません。現在のシステムのプロセッサ数は以下のコマンドで確認することができます。 USER>write $SYSTEM.Util.NumberOfCPUs() 8 以前は、クエリに %PARALLEL キーワードを付与することで並列処理が有効となっておりましたが、IRIS2019.1以降のバージョンより既定で「常時有効」となりました。 管理ポータル: システム管理 > 構成 > SQLとオブジェクトの設定 > SQL 単一プロセス内でクエリを実行 ※チェックを入れると並列処理は行わない(既定はチェックなし) クエリ単位で並列処理を行わないようにする場合は、%NOPARALLEL キーワードを指定します。 例: SELECT * FROM %NOPARALLEL Sample.Person WHERE ... 【注意】%PARALLEL を指定すると、クエリによってはパフォーマンスが低下する可能性があります。たとえば、複数の同時ユーザがいるシステム上で %PARALLEL を指定してクエリを実行すると、全体的なパフォーマンスが低下する場合があります。その場合は、%NOPARALLELで個別に並列処理を行わないようにするか、システム全体で「単一プロセス内でクエリを実行」するように設定します。 詳細は以下のドキュメントをご覧ください。クエリの並列処理
記事
Mihoko Iijima · 2023年3月9日

機械学習を試せるチュートリアル:IntegratedML

開発者の皆さん、こんにちは! 前の記事では、開発者向け情報を集めた「Developer Hub」をご紹介しましたが、この記事では Developer Hub のチュートリアルの中から「機械学習」をテーマとしたチュートリアル:IntegratedML についてご紹介します InterSystems IRISには、機械学習を行うために必要なプロセスのいくつかを自動化するAutoMLの機能が組み込まれていて、機能名として「IntegratedML」と呼んでいます。機能概要については、末尾のビデオをご参照さい。 チュートリアルを始めるための準備は不要で、 ボタンをクリックするだけでチュートリアルを開始できます。 機械学習のテーマは「再入院のリスクの予測」で、1万2千件のデータを利用してモデルを学習させています。 実際に使用するデータはCSVで用意され、こちらに公開されています。 実際のモデル作成、学習、検証、予測に使う構文はSQL文に似ていて、以下の構文を使用しています。 <モデル作成時の構文例> CREATE MODEL ReadmissionModel PREDICTING (MxWillReAdmit) FROM Readmission <学習時の構文例> 全体で1万4千件程度のレコードがあるので、先頭1万2千件を学習用データ、残りを検証用データに使用しています。 学習用データの準備 CREATE VIEW ReadmissionTraining AS SELECT * FROM Readmission where ID<=12000 学習時の構文 TRAIN MODEL ReadmissionModel FROM ReadmissionTraining <検証時の構文> 検証用データの準備 CREATE VIEW ReadmissionValidation AS SELECT * FROM Readmission where ID>12000 検証時の構文 VALIDATE MODEL ReadmissionModel FROM ReadmissionValidation <予測時の構文> SELECT PREDICT(ReadmissionModel) As PredictedReadmission, MxWillReAdmit, * FROM Readmission WHERE ID=1 <予測結果の確率を算出する構文> SELECT PROBABILITY(ReadmissionModel) As PredictedReadmission, * FROM Readmission WHERE ID=1 それぞれの構文は、IRISとCSVがあればどこでも実行できますが、お手元の準備無しにすぐに始めることのできる IntegratedMLチュートリアル をぜひご利用ください! IntegratedMLの機能概要については以下のビデオもぜひご参照ください。 【目次】 0:00 機械学習の概要と課題、AutoMLについて 8:30 IntegratedMLについて 13:20 IntegratedMLの文法 18:32 デモ 26:50 まとめ