2016-07-13 28 views
6

驚くべきことに、私の質問はあまり知られていないことを願っています。GeoDataFrameをSQLデータベースに書き込む

状況によっては、合計で1つ以上のMio観測値を含む複数のcsvファイルがあることがあります。各観測には、とりわけ郵便住所が含まれています。すべてのファイルを単一のGeoDataFrameに読み込み、アドレスをジオコードし、シェイプファイルを指定して空間結合を実行し、各行のポリゴンから情報を保存する予定です。かなり標準的だと思います。これは、1回限りのデータクリーニングプロセスの一部です。

私の目標は、この最終データセットを使用してデータベースをセットアップすることです。これは、データを非常に簡単に共有したり、検索したりできるようにするためです。ウェブサイト上でいくつかの観察をプロットする。また、いくつかの基準に基づいて観測を選択し、いくつかの分析を実行するのは非常に簡単です。

私の問題は、GeoDataFrameをデータベースに挿入する機能がまだ実装されていないと思われることです.GeoPandasはデータベースのサブセットになるはずです(「GeoPandasを使用すると、 PostGISなどの空間データベース」)。

もちろん、各行を繰り返し、各データポイントを「手動で」挿入することもできますが、ここでは最適なソリューションを探しています。任意の回避策については、データ型がデータベースのデータ型と競合する恐れがあります。ここに行くのに "最善の方法"はありますか?

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

答えて

2

私はこれをPostGISデータベース用に実装しました。ここにメソッドを貼り付けることができます。 MySQLの場合は、コードを変更する必要があります。私はpyscopgに基づいて、エンジンと、SQLAlchemyを使用し、それらのパッケージの両方がネイティブ地理タイプを理解していないので、

最初のステップは、WKBの16進文字列にジオコード列を変換することでした。次のステップでは、通常どおり(すべてのジオメトリ列をWKB六角形の文字列を保持するテキスト列に変換する必要がある)、SQL DBにそのデータを書き込んでから、最後にクエリを実行して列の種類をジオメトリに変更します。次の擬似コードを参照してください。geom列はその後、ジオメトリはSRIDを持っていることを期待ので、前に述べたようにKartikの答えは、単一の呼び出しに対してのみ機能@、

# Imports 
import sqlalchemy as sal 
import geopandas as gpd 

# Function to generate WKB hex 
def wkb_hexer(line): 
    return line.wkb_hex 

# Convert `'geom'` column in GeoDataFrame `gdf` to hex 
    # Note that following this step, the GeoDataFrame is just a regular DataFrame 
    # because it does not have a geometry column anymore. Also note that 
    # it is assumed the `'geom'` column is correctly datatyped. 
gdf['geom'] = gdf['geom'].apply(wkb_hexer) 

# Create SQL connection engine 
engine = sal.create_engine('postgresql://username:[email protected]:socket/database') 

# Connect to database using a context manager 
with engine.connect() as conn, conn.begin(): 
    # Note use of regular Pandas `to_sql()` method. 
    gdf.to_sql(table_name, con=conn, schema=schema_name, 
       if_exists='append', index=False) 
    # Convert the `'geom'` column back to Geometry datatype, from text 
    sql = """ALTER TABLE schema_name.table_name 
       ALTER COLUMN geom TYPE Geometry(LINESTRING, <SRID>) 
       USING ST_SetSRID(geom::Geometry, <SRID>)""" 
    conn.execute(sql) 
+0

クール!これは、テーブルが存在しない場合の最初の呼び出しで機能します。しかし、連続した呼び出しは 'DataError:(psycopg2.DataError)Geometry SRID(0)がSRID(4326)の列と一致しません。 – j08lue

+0

'psycopg-postgis'にはインスピレーションがあるかもしれません:https://github.com/yohanboniface/psycopg-postgisしかし、 'shapely' /' geopandas'ではなく、独自の型を実装しています。 – j08lue

+0

この '**は' geom'カラムがジオメトリにSRIDを持つことを期待しているので、データを追加するのではなく、1回の呼び出しで動作します。 – j08lue

5

、データを追加するためには、DataErrorを発生させます。 GeoAlchemyを使用してすべてのケースを処理できます。

# Imports 
from geoalchemy2 import Geometry, WKTElement 
from sqlalchemy import * 

# Use GeoAlchemy's WKTElement to create a geom with SRID 
def create_wkt_element(geom): 
    return WKTElement(geom.wkt, srid = <your_SRID>) 

geodataframe['geom'] = geodataframe['geom'].apply(create_wkt_element) 

db_url = create_engine('postgresql://username:[email protected]:socket/database') 
engine = create_engine(db_url, echo=False) 

# Use 'dtype' to specify column's type 
# For the geom column, we will use GeoAlchemy's type 'Geometry' 
your_geodataframe.to_sql(table_name, engine, if_exists='append', index=False, 
         dtype={geom: Geometry('POINT', srid= <your_srid>)}) 
関連する問題