2016年8月4日木曜日

PowerShellでAzureを操作するときのLocation

PowerShellでAzureを操作するときのLocationですが、いつも使う以外のLocationは忘れがちなので取得方法を書いておきます。

MSDNにはGet-AzureRmLocationコマンドレッドについての記述がありますが、2016年8月現在で使用できないようです。ですので、Get-AzureRmResourceProviderコマンドレッドを使いましょう。
(Get-AzureRmResourceProvider).Locations | Sort-Object | Get-Unique -AsString

結果は以下のようにでます。
Australia East
Australia Southeast
Brazil South
Canada Central
Canada East
Central India
Central US
Central US (Stage)
East Asia
East Asia (Stage)
East US
East US 2
East US 2 (Stage)
Global
global
Japan East
Japan West
MSFT East Asia
MSFT East US
MSFT North Europe
MSFT West US
North Central US
North Central US (Stage)
North Europe
South Central US
South India
Southeast Asia
West Central US
West Europe
West India
West US
West US 2

ちょっと余計なものも出ているような気がしますが。

2016年7月6日水曜日

Microsoft Translatorを利用した日本語→英語翻訳サンプルプログラム

Microsoft Translatorを使う準備
1.Microsoftアカウントを作成します。これはMicrosoft Azure Marketplaceにサインインするために必要になります。
2.Microsoft Azure Marketplace(以下のURL)でサブスクリプション登録を行います。2,000,000文字/月までのデータであれば無償で使えます。
https://datamarket.azure.com/dataset/1899a118-d202-492c-aa16-ba21c33c06cb
3.以下のページからアプリケーションを登録し、「クライアントID」と「顧客の秘密」を取得します。アプリケーションは未作成で問題ありません。
https://datamarket.azure.com/developer/applications/

サンプルプログラムは以下になります。なお、CallMSTranslatorクラスのfromLangとtoLang変数を変更することで、別の言語間の翻訳が可能です。
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Web;
using System.Runtime.Serialization.Json;

namespace MSTranslatorApp
{
    class Program
    {
        //MS Translationへの接続情報
        // clientIdには、事前に登録した「クライアントID」を設定
        // clientSecretには、事前に登録した「顧客の秘密」を設定
        private const string CLIENTID = "<クライアントID>";
        private const string CLIENTSECRET = "<顧客の秘密>";

        static void Main(string[] args)
        {
            // 翻訳前のテキストをコマンドライン引数から取得
            string originalText = args[0];

            CallMSTranslator callMSTranslator = new CallMSTranslator(CLIENTID, CLIENTSECRET);

            // 翻訳語のテキストを取得
            string translatedText = callMSTranslator.TranslateMethod(originalText);

            Console.WriteLine("元のテキスト:" + originalText);
            Console.WriteLine("翻訳テキスト:" + translatedText);
            Console.WriteLine();
            Console.WriteLine("何かキーを押してください...");
            Console.ReadKey();
        }
    }

    class CallMSTranslator
    {
        private string authToken;
        private string clientId;
        private string clientSecret;
        private string baseUrl = "http://api.microsofttranslator.com/v2/Http.svc/Translate?text=";

        private string fromLang = "ja";
        private string toLang = "en";
        private string translatedText;

        public CallMSTranslator(string clientId, string clientSecret)
        {
            // Microsoft Translator APIを呼び出す準備
            this.clientId = clientId;
            this.clientSecret = clientSecret;

            AdmAuthentication admAuth = new AdmAuthentication(clientId, clientSecret);
            AdmAccessToken admToken = admAuth.GetAccessToken();
            authToken = "Bearer " + admToken.access_token;
        }

        public string TranslateMethod(string originalText)
        {
            // Microsoft Translator APIを呼び出して、日本語→英語の翻訳を実行
            string uri = baseUrl + System.Web.HttpUtility.UrlEncode(originalText) + "&from=" + fromLang + "&to=" + toLang;
            HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(uri);
            httpWebRequest.Headers.Add("Authorization", authToken);
            WebResponse response = null;

            try
            {
                response = httpWebRequest.GetResponse();
                using (Stream stream = response.GetResponseStream())
                {
                    System.Runtime.Serialization.DataContractSerializer dcs = new System.Runtime.Serialization.DataContractSerializer(Type.GetType("System.String"));
                    translatedText = (string)dcs.ReadObject(stream);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
            finally
            {
                if (response != null)
                {
                    response.Close();
                    response = null;
                }
            }

            return translatedText;
        }
    }

    public class AdmAccessToken
    {
        public string access_token { get; set; }
        public string token_type { get; set; }
        public string expires_in { get; set; }
        public string scope { get; set; }
    }

    public class AdmAuthentication
    {
        private static readonly string DatamarketAccessUri = "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13";
        private string clientId;
        private string clientSecret;
        private string request;
        private AdmAccessToken token;
        private Timer accessTokenRenewer;

        // アクセストークンの再生成間隔(アクセストークンは10分で失効する)
        private const int RefreshTokenDuration = 9;

        public AdmAuthentication(string clientId, string clientSecret)
        {
            this.clientId = clientId;
            this.clientSecret = clientSecret;

            // クライアントIDと顧客の秘密をエンコード
            this.request = string.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=http://api.microsofttranslator.com", HttpUtility.UrlEncode(clientId), HttpUtility.UrlEncode(clientSecret));
            this.token = HttpPost(DatamarketAccessUri, this.request);

            // アクセストークンの再生成
            accessTokenRenewer = new Timer(new TimerCallback(OnTokenExpiredCallback), this, TimeSpan.FromMinutes(RefreshTokenDuration), TimeSpan.FromMilliseconds(-1));
        }

        public AdmAccessToken GetAccessToken()
        {
            return this.token;
        }

        public void RenewAccessToken()
        {
            AdmAccessToken newAccessToken = HttpPost(DatamarketAccessUri, this.request);

            //アクセストークンの入れ替え
            this.token = newAccessToken;
            Console.WriteLine(string.Format("Renewed token for user: {0} is: {1}", this.clientId, this.token.access_token));
        }

        public void OnTokenExpiredCallback(object stateInfo)
        {
            try
            {
                RenewAccessToken();
            }
            catch (Exception ex)
            {
                Console.WriteLine(string.Format("Failed renewing access token. Details: {0}", ex.Message));
            }
            finally
            {
                try
                {
                    accessTokenRenewer.Change(TimeSpan.FromMinutes(RefreshTokenDuration), TimeSpan.FromMilliseconds(-1));
                }
                catch (Exception ex)
                {
                    Console.WriteLine(string.Format("Failed to reschedule the timer to renew access token. Details: {0}", ex.Message));
                }
            }
        }
        public AdmAccessToken HttpPost(string DatamarketAccessUri, string requestDetails)
        {
            // OAuthリクエストの準備 
            WebRequest webRequest = WebRequest.Create(DatamarketAccessUri);
            webRequest.ContentType = "application/x-www-form-urlencoded";
            webRequest.Method = "POST";
            byte[] bytes = Encoding.ASCII.GetBytes(requestDetails);
            webRequest.ContentLength = bytes.Length;

            using (Stream outputStream = webRequest.GetRequestStream())
            {
                outputStream.Write(bytes, 0, bytes.Length);
            }

            using (WebResponse webResponse = webRequest.GetResponse())
            {
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(AdmAccessToken));
                AdmAccessToken token = (AdmAccessToken)serializer.ReadObject(webResponse.GetResponseStream());
                return token;
            }
        }
    }
}

2016年7月4日月曜日

Polybaseを使用して、Blob StorageからSQL DWへCSVファイル形式のデータをロードする方法

Polybaseを使用して、Blob Storageに格納されているCSVファイル形式のデータをSQL DWにロードする手順です。
基本は以下のドキュメントに従って実行しています。
https://azure.microsoft.com/ja-jp/documentation/articles/sql-data-warehouse-load-from-azure-blob-storage-with-polybase/

なお、今回の手順ではファイル名は「simple_benchmark.csv」、データ形式は「TestId, TextNumber」で、ともに整数データとしています。
また、CSVファイルはストレージアカウント「testdatastorage」、コンテナ「testdata」に格納しています。

1.資格情報を作成
CREATE MASTER KEY;

CREATE DATABASE SCOPED CREDENTIAL AzureStorageCredential
  WITH
    IDENTITY = 'testdatastorage',
    SECRET = '<アクセスキー>';

2.外部データソースの作成
CREATE EXTERNAL DATA SOURCE AzureExtStorage
  WITH (
    TYPE = HADOOP,
    LOCATION = 'wasbs://testdata@testdatastorage.blob.core.windows.net',
    CREDENTIAL = AzureStorageCredential
  );

3.データ形式の構成
CREATE EXTERNAL FILE FORMAT CSVFileFormat
  WITH (
    FORMAT_TYPE = DELIMITEDTEXT,
    FORMAT_OPTIONS (
      FIELD_TERMINATOR = ','
    )
  );

4.データベースのスキーマを作成
CREATE SCHEMA [tst];

5.外部テーブルを作成
CREATE EXTERNAL TABLE [tst].[SimbleExtTab1] 
  (
    [TestId] [int] NOT NULL,
    [TestNumber] [int] NULL
  )
  WITH (
    LOCATION = '/simple_benchmark.csv',
    DATA_SOURCE = AzureExtStorage,
    FILE_FORMAT = CSVFileFormat
  );

6.データをSQL DWにロード
CREATE TABLE [tst].[SimpleTab1]
  WITH (
    DISTRIBUTION = HASH([TestId])
  )
  AS
    SELECT * FROM [tst].[SimbleExtTab1];

7.列ストア圧縮の最適化
ALTER INDEX ALL ON [tst].[SimpleTab1] REBUILD;

8.統計の最適化
CREATE STATISTICS [stat_tst_SimpleTab1_TestId] ON [tst].[SimpleTab1]([TestId]);
CREATE STATISTICS [stat_tst_SimpleTab1_TestNumber] ON [tst].[SimpleTab1]([TestNumber]);

2016年6月20日月曜日

Azure Active Directoryのレポート反映時間

Azure Active Directoryのレポートになかなか表示がされないと思っていたら、タイムラグがあったようです。

「Azure Active Directory レポートの待機時間」というタイトルでドキュメントがありましたので、リンクをはっておきます。
https://azure.microsoft.com/ja-jp/documentation/articles/active-directory-reporting-latencies

2016年6月15日水曜日

Azure SQL Databaseの互換性レベルの変更方法

2016年6月中旬より、Azure SQL Databaseでは新規作成したデータベースの既定の互換性レベルが120から130に変更されます。これ以前に作成した既存のデータベースへの影響はなく、各データベースの互換性レベル(100、110、120のいずれか)が維持されます。

このため、SQL Server 2016のクエリプロセッサの機能強化のメリットを得るために、Azure SQL Databaseの互換性レベルを変更することが推奨されています。

互換性レベルは、以下のSQLで変更できます。
ALTER DATABASE <データベース名> SET COMPATIBILITY_LEVEL = 130

なお、互換性レベルは以下の通りです。
  • SQL Server 2008 + SQL Database v11: 100
  • SQL Server 2012: 110
  • SQL Server 2014 + SQL Database v12: 120
  • SQL Server 2016 + SQL Database v12: 130

2016年6月2日木曜日

Azure Machine Learningのモジュール名変更

気が付いたら、Azure Machine Learningのいくつかのモジュール名が変更になっていました。
  • Project Columns -> Select Columns in Dataset
  • Quantize Data -> Group Data into Bins
  • Sweep Parameters -> Tune Model Hyperparameters
  • Metadata Editor -> Edit Metadata
  • Descriptive Statistics -> Summarize Data
  • Reader -> Import Data
  • Writer -> Export Data
  • Image Reader -> Import Images

2016年5月18日水曜日

SQL DW May 2016 updateにおけるLarge-row support

SQL DWのMay 2016 updateで行あたりのバイト数が32KBという制限が外れ、SQL Serverと同様になったようです。
ただし、May 2016 updateではPolybaseを使った場合の32KBの制限は残っています。(そのうち外れる様子)