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,sqlalchemy
和 geoalchemy2
都没有与 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;
我正在尝试从 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,sqlalchemy
和 geoalchemy2
都没有与 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;