11

このサイトでいくつかの質問を見てきましたが、次の質問に対する答えが見つかりません: How to create multiple NEW tables in a database (私の場合は PostgreSQL を使用しています) from multiple CSV source files , where new database table columns CSV 列内のデータを正確に反映していますか?

CREATE TABLE 構文を問題なく記述でき、CSV ファイルの行/値を読み取ることができますが、CSV ファイルを調べて列の型を正確に判断する方法は既に存在しますか? 自分で作成する前に、これが既に存在するかどうかを確認したかったのです。

まだ存在しない場合、私の考えは、Python、CSV モジュール、および psycopg2 モジュールを使用して、次のような Python スクリプトを作成することです。

  1. CSV ファイルを読み取ります。
  2. レコードのサブセット (10 ~ 100 行?) に基づいて、各行の各列を繰り返し検査し、CSV 内のデータの正しい列タイプを自動的に決定します。したがって、行 1 の列 A の値が 12345 (int) で、列 A の行 2 の値が ABC (varchar) の場合、システムは、組み合わせに基づいて varchar(5) 形式にする必要があると自動的に判断します。最初の 2 つのパスで見つかったデータの。このプロセスは、列のタイプとサイズの可能性を判断するために、ユーザーが必要と感じた回数だけ実行できます。
  3. CSV の列検査によって定義された CREATE TABLE クエリを作成します。
  4. テーブル作成クエリを実行します。
  5. データを新しいテーブルにロードします。

このようなツールは、SQL、PostgreSQL、Python のいずれかに既に存在しますか?それとも、これを達成するために使用する必要がある別のアプリケーション (pgAdmin3 に似ています) はありますか?

4

3 に答える 3

7

私は似たようなことを扱ってきましたが、ソースファイルを調べてデータ型を盗聴する独自のモジュールを作成することになりました。すべての否定論者の間でいくつかの知恵がありますが、これを行う価値がある理由もあります。特に、入力データ形式を制御できない場合 (政府のオープンデータを扱う場合など) です。過程の中で:

  1. 非常に時間がかかりますが、行の小さなサンプルではなく、ファイル全体を実行する価値があります。数千行ごとにテキストがあることが判明した数値として列にフラグを立て、インポートに失敗すると、より多くの時間が浪費されます。
  2. 疑わしい場合は、テキスト型にフェールオーバーします。これは、不適切なインポートで失われたデータを試行して推測するよりも、後でそれらを数値または日付/時刻にキャストする方が簡単だからです。
  3. 整数列と思われる先頭のゼロをチェックし、存在する場合はテキストとしてインポートします。これは、ID/アカウント番号に関する一般的な問題です。
  4. 自動的に検出されたいくつかの列の型を手動でオーバーライドする方法を自分で用意して、ほとんどの列を自動的に入力する利点とセマンティックな認識を融合できるようにします。
  5. 日付/時刻フィールドは悪夢であり、私の経験では通常、手動処理が必要です。
  6. 後でこのテーブルにデータを追加する場合は、タイプの検出を繰り返さないでください。データベースからタイプを取得して、一貫性を確保してください。

自動型検出を行う必要がないようにできる場合は、回避する価値がありますが、それが常に実用的であるとは限らないため、これらのヒントが役立つことを願っています。

于 2014-02-20T19:04:13.843 に答える
1

事前に構造を知っておく必要がありそうです。最初の行を読んで、取得した列の数を確認してください。

CSV には型情報が含まれていないため、データのコンテキストから推測する必要があります。

前の少し間違った答えを改善すると、 x 個のテキスト列を持つ一時テーブルを作成し、データを入力してからデータを処理できます。

BEGIN;
CREATE TEMPORARY TABLE foo(a TEXT, b TEXT, c TEXT, ...) ON COMMIT DROP;
COPY foo FROM 'file.csv' WITH CSV;
<do the work>
END;

このファイルは、postgresql プロセス自体からアクセスできる必要があります。これにより、セキュリティ上の問題が発生します。その他のオプションは、STDIN を介してフィードすることです。

HTH

于 2012-11-17T11:15:25.087 に答える