Geopandas to_sql 在 mysql 中将几何列显示为文本

Geopandas to_sql shows geometry column as text in mysql

我正在尝试从 geojson 中获取多面体数据,将其读入数据框,然后在 mysql 中创建包含数据的 table。

令我感到奇怪的是,检查脚本末尾的 dtype 会将几何列正确显示为 geometry。但是,检查 mysql 数据库时,此列显示为 text。尝试将列转换为几何或多面体类型会引发错误

1416 - Cannot get geometry object from data you send to the GEOMETRY field

我尝试了以下查询,这可能是我的问题所在?

ALTER TABLE [table]
MODIFY COLUMN [column] GEOMETRY

类似问题给出了将数据转换为WKT或WKB的答案。 但是,使用 to_wkb(或 to_wkt)方法然后使用 运行 查询也会导致前面提到的错误。我也试过只做我自己的功能但没有运气。 Python 下面的代码。

import geopandas
from geoalchemy2 import Geometry
from sqlalchemy import create_engine, types


df = geopandas.read_file('geodata.geojson')

# geodataframe = df.to_wkb()

hostname="localhost"
dbname="mydbname"
uname="iamroot"
pwd = "madeyoulook"

engine = create_engine(f'''mysql://{uname}:{pwd}@{hostname}/{dbname}''')

df.to_sql('geodatacounty', engine, if_exists='replace', index=False, dtype={'shape_leng': types.FLOAT , 'shape_area': types.FLOAT, '`geometry`': Geometry(geometry_type='MULTIPOLYGON', srid=4326)})

AFAIK,sqlalchemygeoalchemy2 都没有与 MySQL 直接兼容的几何类型,因此您拥有的可能适用于 PostGIS 的示例不会生成语法正确的MySQL 的声明。因此,您需要解决这个问题,例如.

如果您的多边形数据位于 TEXT 类型的列中,您可以使用 ST_GeomFromText() 将其转换为几何图形。为确保您可以正确存储结果,首先创建一个类型为 GEOMETRY(或 MULTIPOLYGON 或任何您想要的)的附加列:

ALTER TABLE tab ADD COLUMN newcolumn GEOMETRY;

然后更新该列:

UPDATE tab SET newcolumn = ST_GeomFromText(oldcolumn);

注:

  • 如果您首先在导入数据时遇到困难,changing the encoding of your db may help
    ALTER DATABASE mydbname CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
    
  • 如果您一开始就遇到几何图形的 WKT 文本表示对于 TEXT 列来说太大的错误,您可以明确使用 [=26= 的 dtype 参数] 将它们存储在 LONGTEXT 列中:
    from sqlalchemy.dialects.mysql import LONGTEXT
    
    gdf.to_sql('tab', con, if_exists='replace', index=False, dtype = {'geometry': LONGTEXT})
    
    (这也适用于 MEDIUMTEXT)。

完整的 Python 示例,在 MySQL 5.7:

的快速测试中对我有用
import geopandas as gpd
from sqlalchemy import create_engine, sql

hostname = 'localhost'
dbname = 'mydbname'
uname = 'iamroot'
pwd = 'madeyoulook'

engine = create_engine(f'''mysql+pymysql://{uname}:{pwd}@{hostname}/{dbname}''')

gdf = gpd.read_file('geodata.geojson')
gdf = gdf.to_wkt()

with engine.connect() as con:
    # may not be necessary, see above. 
    con.execute(sql.text("""ALTER DATABASE mydbname CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;"""))

    gdf.to_sql('tab', con, if_exists='replace', index=False)

    con.execute(sql.text("""ALTER TABLE mydbname.tab ADD COLUMN new_geometry GEOMETRY;"""))
    con.execute(sql.text("""UPDATE mydbname.tab SET new_geometry = ST_GeomFromText(geometry);"""))

然后您应该在 table tab 中具有 GEOMETRY 类型的相应列 new_geometry,它以 MySQL 的内部格式存储几何.你可以例如在该列上使用 the MySQL Geometry Format Conversion Functions 来取回 WKT 表示:

SELECT ST_AsWKT(new_geometry) from tab;