python - Geopandas to_sql 在 mysql 中将几何列显示为文本
问题描述
我正在尝试从 geojson 获取多面数据,将其读入数据框,然后在 mysql 中创建一个包含数据的表。
对我来说奇怪的是,检查dtype
脚本末尾的 将几何列正确显示为geometry
. 但是,检查 mysql db 此列显示为text
. 尝试将列转换为几何或多面体类型会引发错误
1416 - 无法从您发送到 GEOMETRY 字段的数据中获取几何对象
我尝试了以下查询,这可能是我的问题所在?
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
,然后将数据转换为GEOMETRY
.
如果您在TEXT
类型列中有多边形数据,则可以使用ST_GeomFromText()
. 为确保您可以正确存储结果,请先创建一个额外的类型GEOMETRY
(MULTIPOLYGON
或任何您想要的)列:
ALTER TABLE tab ADD COLUMN newcolumn GEOMETRY;
然后更新该列:
UPDATE tab SET newcolumn = ST_GeomFromText(oldcolumn);
笔记:
- 如果您首先在导入数据时遇到困难,那么更改数据库的编码可能会有所帮助:
ALTER DATABASE mydbname CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
- 如果您首先遇到几何图形的 WKT 文本表示对于列而言太大的错误
TEXT
,您可以显式使用dtype
参数 of.to_sql()
将它们存储在LONGTEXT
列中:
(这也适用于from sqlalchemy.dialects.mysql import LONGTEXT gdf.to_sql('tab', con, if_exists='replace', index=False, dtype = {'geometry': LONGTEXT})
MEDIUMTEXT
)。
在 MySQL 5.7 的快速测试中对我有用的完整 Python 示例:
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);"""))
然后,您应该在表中具有相应new_geometry
的类型列,该列以 MySQL 的内部格式存储几何。例如,您可以在该列上使用MySQL 几何格式转换函数来取回 WKT 表示:GEOMETRY
tab
SELECT ST_AsWKT(new_geometry) from tab;
推荐阅读
- python - 从一个表中提取小时值并在另一个表中填充一小时增量的“桶”的函数
- spock - 如何从 spock 测试框架访问 application.yml 文件
- mysql - 计算数据类型 TIME 的十进制数
- java - 在 Android API28 上关闭应用程序时,WorkManager 不会定期运行
- javascript - 在 JavaScript 中实现节点存储功能
- angular - 如何使用 PrimeNg 拖放保留列表 A 中已从列表 A 拖放到列表 B 中的元素?
- python-2.7 - 无法在 Google App Engine Standard 上导入 cygrpc
- c - 在 C 中实现 Shell:输出重定向是将输出文件名写入输出文件而不是命令结果
- python - 是否可以从单独的模块加载 SqlAlchemy 表定义而不会导致“未使用的导入语句”?
- powershell - 使用 Powershell 从 AD 中提取属性