2

数百のファイルにまたがる大量のデータ セットがあります。どうやら、エンコーディングの問題がいくつかあるようです (ほとんどが UTF-8 ですが、有効でない文字もあるようです)。https://msdn.microsoft.com/en-us/library/azure/mt764098.aspxによると、エンコードエラーがある場合、silent フラグを true に設定しても実行時エラーが発生します (単にスキップすることを目的として)エラー行)。

その結果、カスタム エクストラクタを作成する必要があります。https://blogs.msdn.microsoft.com/data_otaku/2016/10/27/a-fixed-width-extractor-for-azure-data-lakeの例の簡略化されたバージョンを主に実行するものを書きました-analytics/は、行を取得し、区切り文字で分割し、try ブロック内の値を返すだけです。例外があれば、それを処理して次に進みます。

残念ながら、USQL スクリプト自体でこのエクストラクタを実際に参照する際に問題が発生しています。上記のリンクのガイダンスに従うと、別のアセンブリにロジックを記述し、それを構築し、それを ADLS データベース/アセンブリに登録してからREFERENCE ASSEMBLY MyExtractors;、スクリプトの先頭に含めることを提案しています (これが使用される名前空間であるため)。以下の Using ステートメントでは、次のように呼び出していUSING new SimpleExtractor();ますtype or namespace cannot be found。さらに、より正確に using ステートメントで使用しようとするとUSING new MyExtractors.SimpleExtractor();、上記の USING ステートメントを引用して同じエラーが発生します。

その後、 https://azure.microsoft.com/en-us/documentation/articles/data-lake-analytics-u-sql-develop-user-defined-operators/の古いソースで追加のドキュメントを見つけました。同じことですが、コード ビハインド ファイルにあります。別のアセンブリを削除し、ロジックをそのファイルのクラスにコピーしました。REFERENCE ASSEMBLY手順 6 の例にはステートメントが表示されていませんが、再度実行すると、 type or namespace name cannot be found.

ここで何かが古くなっていることを期待して最新のリリースノートを見ると、USINGステートメントを使用する場合、実際に実行する前に(最初の試行のように)カスタムコードのアセンブリへの参照が必要であることがわかります。私はそれを使用しています。

USQL で UDO を適切に参照する方法、またはランタイムがエンコード例外をサイレントに処理する方法 (およびスキップする方法) について、誰かがガイダンスを提供してもらえますか?

エクストラクタ自体での私のロジックは次のようになります。

using System.Collections.Generic;
using System.IO;
using System.Text;
using Microsoft.Analytics.Interfaces;

namespace Utilities
{
    [SqlUserDefinedExtractor(AtomicFileProcessing = true)]
    public class ModifiedTextExtractor : IExtractor
    {
        //Contains the row
        private readonly Encoding _encoding;
        private readonly byte[] _row_delim;
        private readonly char _col_delim;

        public ModifiedTextExtractor()
        {
            _encoding = Encoding.UTF8;
            _row_delim = _encoding.GetBytes("\r\n");
            _col_delim = '\t';
        }

        public override IEnumerable<IRow> Extract(IUnstructuredReader input, IUpdatableRow output)
        {
            //Read the input line by line
            foreach (var current in input.Split(_row_delim))
            {
                using (var reader = new StreamReader(current, this._encoding))
                {
                    var line = reader.ReadToEnd().Trim();

                    //If there are any single or double quotes in the line, escape them
                    line = line.Replace(@"""", @"\""");

                    var count = 0;

                    //Split the input by the column delimiter
                    var parts = line.Split(_col_delim);

                    foreach (var part in parts)
                    {
                        output.Set<string>(count, part);
                        count += 1;
                    }
                }
                yield return output.AsReadOnly();
            }
        }
    }
}

そして、USQLステートメントでそれを使用しようとしている方法のスニペット(アセンブリとして登録した後):

REFERENCE ASSEMBLY [Utilities];

CREATE VIEW MyView AS ...
USING new Utilities.ModifiedTextExtractor();

ありがとうございました!

4

2 に答える 2

2

ビューがカスタム コードを参照できないという問題が発生しています。U-SQL では、すべてのオブジェクトにコンテキスト仕様 (本体内の参照アセンブリなど) を含める必要があります (これにより、オブジェクトがより自己完結型になり、オブジェクトのユーザーに知られていない、潜在的に長い依存関係の行をプルするという問題が回避されます)。 )。

必要なことは、VIEW をテーブル値関数に変換することです。

CREATE FUNCTION MyFunct(/* optional parameters */) RETURNS @res AS
BEGIN
  REFERENCE ASSEMBLY [Utilities];
  @res = EXTRACT ... USING new Utilities.ModifiedTextExtractor();
END;

SELECT次に、次のように関数を呼び出します (ステートメントで行セット エイリアスを指定する必要があることに注意してください)。

@data = SELECT ... FROM MyFunct() AS f WHERE ...;

または、プロジェクションまたはフィルターを適用したくない場合:

@data = MyFunct();

ビューと同様に、テーブル値関数はインライン化されます。

于 2016-11-11T18:35:23.410 に答える
0

この問題に対する別のアプローチは、行の拒否をサポートする Azure SQL Data Warehouse と Polybase を使用することです。

1) 外部ファイルの ADW に外部テーブルを作成します。

CREATE EXTERNAL TABLE ext.mycsv (
    colA INT NOT NULL,
    colB INT NOT NULL,
    colC INT NOT NULL
)
WITH (
    DATA_SOURCE = eds_mycsv,
    LOCATION = N'/myblobstorage/',
    FILE_FORMAT = eff_csv,
    REJECT_TYPE = VALUE,
    REJECT_VALUE = 1
)

外部テーブルは、単一のファイルまたはディレクトリ (私の例と同じ構造を持つ複数のファイル) を指すことができます。reject_value が 1 の場合、ジョブ全体を失敗させることなく、1 つの行を失敗させることができます。これはパーセンテージにすることもできます。たとえば、「ロード全体を失敗させることなく、行の 3% を失敗させることができます。このステートメントは、失敗した行に関する情報も提供します。詳細についてはREJECT_TYPE、 およびREJECT_VALUE ここを参照してください。

ADW のもう 1 つの優れた点は、使用していないときに一時停止できることです。

2) ADW で内部テーブルを作成して具体化します。

CREATE TABLE dbo.mycsv
WITH 
(   
    CLUSTERED COLUMNSTORE INDEX,
    DISTRIBUTION = ROUND_ROBIN
)
AS
SELECT * FROM ext.mycsv;

3) U-SQL を使用して Azure Data Lake Analytics (ADLA) 内に外部テーブルを作成し、外部データ ソースを使用して "データが存在する場所、つまりウェアハウス内でデータをクエリ" します。

// Create external table which is in SQL DW
CREATE EXTERNAL TABLE IF NOT EXISTS adlaExt.mycsv
(
    colA        int,
    colB        int,
    colC        int
)
FROM ds_adw LOCATION "dbo.mycsv";

4) U-SQL で外部テーブルをクエリします。例:

// Query external table
@e =
    SELECT *
    FROM dbo.mycsv;


// Join with internal table
@q =
    SELECT a.*, b.someColumn
    FROM @e AS a
            INNER JOIN
                dbo.someOtherTable AS b
            ON a.colA == b.n_colA;


// Output it
OUTPUT @q TO "/output/output.csv"
USING Outputters.Csv();

必要に応じて ADLA にインポートします。ADLA でのフェデレーテッド クエリのセットアップに関する Jorg Klein によるすばらしいブログ投稿がここにあります。

ネイティブの Azure コンポーネントを使用しているため、これはカスタム エクストラクターを作成するよりもはるかに安全です。Polybase はまだ ADLA をサポートしていませんが、将来のある時点でほぼ確実にサポートされるようになり、その時点で設計が簡素化される可能性があります。

于 2016-11-04T00:51:24.713 に答える