GeoPandas.GeoDataFrame: 类型 "geometry" 不存在

GeoPandas.GeoDataFrame: type "geometry" does not exist

Ubuntu 20.04.3 LTS (WSL2)

菲奥娜 1.8.21
地理pandas 0.10.2
geopandas-base 0.10.2
geopy 2.2.0
麻木 1.22.3
pandas1.4.1
psycopg2 2.9.3
pyproj 3.3.0
rtree 0.9.7
匀称 1.8.0

postgresql-14 14.2-1.pgdg20.04+1
postgresql-14-postgis-3 3.2.1+dfsg-1.pgdg20.04+1

正在尝试将几个多边形发送到 postgresql 数据库 (postgis)。运气不好 -.-' 总是收到相同的错误消息。有人可以帮助我吗?

Exception in thread Thread-2 (_create_searchwindows):
Traceback (most recent call last):
  File "/home/user/miniconda3/envs/geo/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 1808, in _execute_context
    self.dialect.do_execute(
  File "/home/user/miniconda3/envs/geo/lib/python3.10/site-packages/sqlalchemy/engine/default.py", line 732, in do_execute
    cursor.execute(statement, parameters)
psycopg2.errors.UndefinedObject: type "geometry" does not exist
LINE 4:  geometry geometry(POLYGON,25832)
                  ^


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/user/miniconda3/envs/geo/lib/python3.10/threading.py", line 1009, in _bootstrap_inner
    self.run()
  File "/home/user/miniconda3/envs/geo/lib/python3.10/threading.py", line 946, in run
    self._target(*self._args, **self._kwargs)
  File "/home/user/github/create_searchwindows/searchwindow_creator.py", line 143, in _create_searchwindows
    grid.to_postgis(self.args.searchwindows_tablename,self.engine,if_exists="append",index=True,index_label="Index")
  File "/home/user/miniconda3/envs/geo/lib/python3.10/site-packages/geopandas/geodataframe.py", line 1808, in to_postgis
    geopandas.io.sql._write_postgis(
  File "/home/user/miniconda3/envs/geo/lib/python3.10/site-packages/geopandas/io/sql.py", line 431, in _write_postgis
    gdf.to_sql(
  File "/home/user/miniconda3/envs/geo/lib/python3.10/site-packages/pandas/core/generic.py", line 2963, in to_sql
    return sql.to_sql(
  File "/home/user/miniconda3/envs/geo/lib/python3.10/site-packages/pandas/io/sql.py", line 697, in to_sql
    return pandas_sql.to_sql(
  File "/home/user/miniconda3/envs/geo/lib/python3.10/site-packages/pandas/io/sql.py", line 1729, in to_sql
    table = self.prep_table(
  File "/home/user/miniconda3/envs/geo/lib/python3.10/site-packages/pandas/io/sql.py", line 1628, in prep_table
    table.create()
  File "/home/user/miniconda3/envs/geo/lib/python3.10/site-packages/pandas/io/sql.py", line 842, in create
    self._execute_create()
  File "/home/user/miniconda3/envs/geo/lib/python3.10/site-packages/pandas/io/sql.py", line 828, in _execute_create
    self.table.create(bind=self.pd_sql.connectable)
  File "/home/user/miniconda3/envs/geo/lib/python3.10/site-packages/sqlalchemy/sql/schema.py", line 950, in create
    bind._run_ddl_visitor(ddl.SchemaGenerator, self, checkfirst=checkfirst)
  File "/home/user/miniconda3/envs/geo/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 2119, in _run_ddl_visitor
    visitorcallable(self.dialect, self, **kwargs).traverse_single(element)
  File "/home/user/miniconda3/envs/geo/lib/python3.10/site-packages/sqlalchemy/sql/visitors.py", line 524, in traverse_single
    return meth(obj, **kw)
  File "/home/user/miniconda3/envs/geo/lib/python3.10/site-packages/sqlalchemy/sql/ddl.py", line 893, in visit_table
    self.connection.execute(
  File "/home/user/miniconda3/envs/geo/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 1295, in execute
    return meth(self, multiparams, params, _EMPTY_EXECUTION_OPTS)
  File "/home/user/miniconda3/envs/geo/lib/python3.10/site-packages/sqlalchemy/sql/ddl.py", line 80, in _execute_on_connection
    return connection._execute_ddl(
  File "/home/user/miniconda3/envs/geo/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 1387, in _execute_ddl
    ret = self._execute_context(
  File "/home/user/miniconda3/envs/geo/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 1851, in _execute_context
    self._handle_dbapi_exception(
  File "/home/user/miniconda3/envs/geo/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 2032, in _handle_dbapi_exception
    util.raise_(
  File "/home/user/miniconda3/envs/geo/lib/python3.10/site-packages/sqlalchemy/util/compat.py", line 207, in raise_
    raise exception
  File "/home/user/miniconda3/envs/geo/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 1808, in _execute_context
    self.dialect.do_execute(
  File "/home/user/miniconda3/envs/geo/lib/python3.10/site-packages/sqlalchemy/engine/default.py", line 732, in do_execute
    cursor.execute(statement, parameters)
sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedObject) type "geometry" does not exist
LINE 4:  geometry geometry(POLYGON,25832)
                  ^

[SQL:
CREATE TABLE public.sw32 (
        "Index" BIGINT,
        geometry geometry(POLYGON,25832)
)

]
(Background on this error at: https://sqlalche.me/e/14/f405)

我确定,数据库中的 postgis 扩展已激活。如果我使用 psql 在数据库中创建带有几何列的 table,它的工作非常好。安装的 python 软件包似乎有些不正确。有人遇到过同样的麻烦吗?

代码如下所示:

import geopandas as gpd
from sqlalchemy import create_engine
engine = create_engine(f'postgresql://{db_user}:{db_password}@{db_host}:{db_port}/')
grid = gpd.GeoDataFrame(polygons,geometry="geometry",crs="EPSG:25832")
grid.to_postgis("testtable",engine,if_exists="append",index=True,index_label="Index") 

编辑 1:

我目前的解决方法是将多边形存储在 *.shp 文件中并执行 shp2psql 以将多边形发送到数据库。代码如下所示:

grid.to_file("tmp_name.shp")
cmd = f"shp2pgsql -s 25832 tmp_name.shp public.testtable |psql postgresql://{db_user}:{db_password}@{db_host}:{db_port}/{database}"
os.system(cmd)

确实我的连接字符串不正确。忘了提到数据库。随着连接字符串的调整如下:

engine = create_engine(f'postgresql://{db_user}:{db_password}@{db_host}:{db_port}/{database}')

一切正常!

可能与您的“geoalchemy2”版本有关。您的 geoalchemy2 版本应该是“0.9.2”。