1CおよびETL


ETLおよび1C。 データ抽出


初見


ETLスペシャリストとして、1Cからデータを取得する必要がある場合、これはデータベース構造を理解しようとするときに最初に確認できるものです(MSSQLの場合、他のDBMSでも同様です)。



テーブルとフィールドの名前にはビジネス上の意味はなく、外部キーはありません。

1Cについての愛情深いカップル。 その中の実際のDBMSテーブルは、開発者が見るオブジェクトの背後に隠されています。開発者は、データベースの実際の構造を知らないことがよくあります。 はい...そして、すべてのコードはロシア語です。 さらに、SQLを使用した文字列表現を取得するのがほとんど不可能な列挙型があります。 詳細はこちら

データベース(およびファイルバージョンの1C)がない場合もありますが、これはもちろん、DBMSツールを使用せずに統合を指示します。

しかし、すべてが見た目ほど悪くないので、絶望しないでください。

気配りのある外観


1Cからデータをキャプチャするには、2つの方法があります。

「高レベル」インターフェースの実装


ファイルアップロード、Web / JSONサービス、およびETLと互換性のある1Cのその他の機能を使用できます。

+
  1. 1Cに登る必要はありません。 1C側のすべては1Snikiによって行われるべきです
  2. 1Cライセンスポリシーに違反していない

-
  1. エラーの別の原因は、追加のアップロード、ダウンロード、
    スケジュール、ロボット
  2. 1Cインターフェースの機能により、これは非常に遅くなります
  3. キャプチャされたデータに変更がある場合、アップロードに変更を加える必要があります(ただし、これは構成システムによって回避できます)
  4. これにより、DBMSを直接操作するよりもデータの整合性に多くのエラーが発生します

DBMSの実装


+
  1. より速く
  2. 適切なアプローチでウェアハウス内のデータの完全性を確保できます

-
  1. 1Cとのライセンス契約に違反します

したがって、長所と短所を比較検討した後、DBMSを使用して統合を構築するか、少なくとも
次にそれをどうするかを考えてください。

データマッピング


1C側で理解されるように、ビジネスデータを実際のデータベーステーブルに関連付けるには、1C自体で少し魔法をかける必要があります。つまり、1Cメタデータの説明を使用可能な形式で(ビジネスオブジェクトとテーブルに関連して)取得する必要があります。
繰り返しますが、少なくとも3つのアプローチがあります。

  1. com-connection、web / jsonサービスを使用して、1Cから対応表を取得する
  2. 1C側でも同じことを行い、メタデータテーブルを作成します
  3. 同じデータベースに保存されているバイナリファイルを解析する

3番目の方法は、1Cが警告なしに内部を変更する習慣があるため、多少危険です。 そして同時に、非常に複雑です。
1と2の選択はそれほど明白ではありませんが、私の好みでは、事前に作成されたテーブルを使用する方が日常の使用ではるかに便利で信頼性が高く、純粋なSQL以外を使用する必要はありません。

1Cを使用してテーブルの関連性を保存および維持し、構成を更新するたびに更新する方が便利です。 同時に、ETLはViewを使用できます。これにより、データはより消化しやすい形式で既に表示されます。

メタデータテーブルの準備


構成メタデータを含む1Cでオブジェクトを作成します(残念ながら、これはスクリプトでは実行できませんが、1Cニックネームに指示を与えることができます)

情報レジスター構造構成
フィールド:
NameTablesStorage
NameTables
SynonymTables
予定
NameFieldsStorage
シノニムフィールド

全行150文字



非正規化されていることがわかりますが、非常に便利でシンプルです。

構造を埋めるためにコード1C:

 = (,);  = ..();           .   = .(); . = .; . = .; . = .(.); . = .; . = .; . = .(.); ; ; .(); 

繰り返しますが、ロシア語にもかかわらず、すべてが非常にシンプルで明白です。 構成を更新するたびにこのコードを実行する必要があります。 これは、処理の手で、またはスケジュールされたタスクの助けを借りて行うことができます。

テーブルは、クライアントモードとSQ​​L側の両方で、名前を知って表示できます。

  SELECT * FROM _InfoReg27083 ORDER BY _Fld27085 

(_InfoReg27083-1Cが構造を持つレジスタテーブルに付けた名前、_Fld27085-ストレージテーブルの名前を持つフィールドの名前)

ビューをより便利にすることができます。

構成を変更できない場合は、com経由で接続するか、ETLに関連するデータベースのテーブルへのアンロード処理を追加することにより、テーブルを作成できます。

そして、ここで、テーブルの種類と、それらが必要な理由について説明します(ITS 1Cへのアクセスが必要です)

次のステップは、データをマップし、変換を記述することです。

野原Field1c変換...
_Fld15704文書、商品の実現、サービス、重量Check> = 0、ラウンド(10,2)、......

そこで、今後の作業で使用できるマッピングテーブルを取得しました。

データ変更のキャプチャ


現在、データの変更をキャプチャするための戦略の面で。 ここでも、いくつかのオプションがあります。 テーブル全体を取得する方が簡単です。もちろん、サーバーに多大な追加コストがかかる可能性があります。

ただし、他の方法もあります。

  1. オブジェクトバージョンを使用する
  2. 交換プランを使用する

オブジェクトバージョンを使用する


「参照」タイプのオブジェクトの場合、1Cはバージョンをサポートします。 オブジェクトのバージョン番号は、 _versionバイナリフィールドに書き込まれます。これは、レコードが更新されるたびに慎重に更新されます。 たとえば、MSSQLでは、これはタイムスタンプ型のフィールドです。 バージョンは、「ドキュメント」、「ディレクトリ」、「ビジネスプロセス」、「タスク」、「アカウントのチャート」、「特性のタイプのチャート」、「定数」タイプのオブジェクトに対してサポートされています。 バージョンの使用は非常に簡単で、ステージング領域にオブジェクトの最新バージョンの値を保持し、次の更新中にバージョンフィールドでより大きいオブジェクトを選択します。 「メイン」オブジェクトと一緒に、構造(_DocumentXXX_IDRRefまたは_ReferenceXXX_IDRRefのフィールド-メインテーブルへのリンク)の表部分(目的-「表部分」を参照)を選択することを忘れないでください。

交換プランを使用する


非参照型の場合、このアプローチは適切ではありませんが、オブジェクト「交換計画」を使用できます。 構造テーブルでは、それらの目的は「登録の変更」です。 構成オブジェクトごとに個別の交換計画テーブルが作成されます。

データベースレベルでは、これは次の構造のようなテーブルです。

_NodeTRef、-交換計画の「ノード」タイプの識別子。 彼は私たちにとってあまり面白くない
_NodeRRef、-交換計画ノード識別子
_MessageNo、-メッセージ番号

次に、「メイン」テーブルの主要なフィールドがあります。 それらは、交換計画テーブルが関連付けられているテーブルのタイプによって異なります。

_IDRRef-この場合、ディレクトリまたはドキュメントのID
たぶんこのように:
_RecorderTRef
_RecorderRRef

これは、累積レジスタ、レジストラに従属する情報レジスタ、または会計レジスタの変更のテーブルになります。 レジストラに従属していない場合、情報レジスタテーブルキーにもキーが存在する場合があります。

このような変更登録テーブルが存在するためには、1C configuratorの交換計画に必要なオブジェクトを含める必要があります。 さらに、交換計画ノードを作成する必要があり、その名前の識別子(_IDRRef)を使用する必要があります。

交換計画テーブルは、構造内にあります(上記を参照)。 なぜなら 交換計画では、ストレージだけでなくすべてのノードの変更が記録されるため、選択を必要な_NodeRRefに制限する必要があります。 交換計画は参照オブジェクトにも使用できますが、私の意見では、これはリソースの無駄です。

交換計画を通じてデータを収集する方法:

最初に、交換計画の更新を作成し、任意の_MessageNO(常に1よりも良い)を配置します。

例えば

UPDATE _DocumentChangeRec18901 set _MessageNO = 1 WHERE _NodeRRef = @_NodeRRef

次に、データテーブルからデータを選択し、キーで交換計画のテーブルにリンクします

SELECT [fieldslist] FROM _Document18891 inner join _DocumentChangeRec18901 ON _Document18891._IDRRef = _DocumentChangeRec18901._IDRRef and _MessageNO = 1 AND _NodeRRef = @_NodeRRef

変更テーブルのエントリを削除して、変更フェンスを確認します

DELETE FROM _DocumentChangeRec18901 WHERE _MessageNO = 1 AND _NodeRRef = @_NodeRRef

合計:ETL側で1Cメタデータを読み取る方法と、データをキャプチャする方法を学びました。 ETLプロセスの残りのステップはよく知られています。 たとえば、 ここで読むことができます

Source: https://habr.com/ru/post/J334798/


All Articles