Jho*_*nny 7 python mysql pandas geopandas
我希望我的问题不是荒谬的,因为令人惊讶的是,这个问题在热门网站上显然还没有被提及(据我所知).
情况是我有几个csv文件,总共包含超过1个Mio观测值.每个观察都包含一个邮政地址.我打算将所有文件读入单个GeoDataFrame,对地址进行地理编码,在给定shapefile的情况下执行空间连接,并为每行保存多边形中的一些信息.我想这是相当标准的.这是一次性数据清理过程的一部分.
我的目标是使用此最终数据集设置数据库.这是因为它允许我非常容易地共享和搜索数据,以及例如在网站上绘制一些观察结果.此外,它使得根据某些标准选择观察结果变得非常容易,然后进行一些分析.
我的问题是插入GeoDataFrame到数据库的功能似乎并没有被还没有实现 - 这显然是因为GeoPandas应该是对数据库的一个替补多("GeoPandas使您可以轻松地做在巨蟒行动,否则将需要的空间数据库,作为PostGIS").
当然,我可以遍历每一行并"手动"插入每个数据点,但我在这里寻找最佳解决方案.对于任何解决方法,我也担心数据类型可能与数据库的数据类型冲突.这里有"最好的方式"吗?
谢谢你的帮助.
小智 10
如前所述,@ Kartik的答案仅适用于单个调用,用于追加它引发的数据,DataError因为该geom列然后期望几何具有SRID.您可以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:password@host: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>)})
Run Code Online (Sandbox Code Playgroud)
因此,我只是为PostGIS数据库实现了这一点,可以在这里粘贴我的方法。对于MySQL,您必须修改代码。
第一步是将经过地理编码的列转换为WKB十六进制字符串,因为我将SQLAlchemy与基于pyscopg的引擎一起使用,而且这两个软件包都不是本地理解地理类型的。下一步是照常将数据写入SQL DB(请注意,所有几何列都应转换为包含WKB十六进制字符串的文本列),最后通过执行查询将列的类型更改为几何。请参考以下伪代码:
# 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:password@host: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)
Run Code Online (Sandbox Code Playgroud)