Repository: geopandas/geopandas

Issue:
BUG: to_postgis method raises exception on append
- [x] I have checked that this issue has not already been reported.

- [x] I have confirmed this bug exists on the latest version of geopandas.

- [ ] (optional) I have confirmed this bug exists on the master branch of geopandas.

---

#### Code Sample

```python
import geopandas as gpd
import sqlalchemy
from shapely.geometry import Point, Polygon

engine = sqlalchemy.create_engine('postgresql+psycopg2://user:password@localhost:5432/db')

gdf = gpd.GeoDataFrame([
    {
        'a': 1,
        'geometry': Point(1, 1)
    },
    {
        'a': 2,
        'geometry': Polygon(shell=((1,1), (1,2), (2,2)))
    }
])

with engine.connect() as conn:
    gdf.to_postgis('test_table', conn)
    gdf.to_postgis('test_table', conn, if_exists='append')


```

#### Problem description

When I try to append a GDF without CRS to an existing table in PostGIS (also without CRS), Geopandas raises the error

`ValueError: The CRS of the target table (EPSG:0) differs from the CRS of current GeoDataFrame (EPSG:-1).`

(In the code above, the last line raises this error)

#### Expected Output

The GDF should correctly be appended to the PostGIS table and should not raise a `ValueError`

#### Output of ``geopandas.show_versions()``

<details>

SYSTEM INFO
-----------
python     : 3.8.12 | packaged by conda-forge | (default, Sep 16 2021, 02:08:29)  [GCC 9.4.0]
executable : /home/chofmann/.conda/envs/detekt/bin/python
machine    : Linux-5.4.0-80-generic-x86_64-with-glibc2.10

GEOS, GDAL, PROJ INFO
---------------------
GEOS       : 3.9.1
GEOS lib   : /home/chofmann/.conda/envs/detekt/lib/libgeos_c.so
GDAL       : 3.3.1
GDAL data dir: /home/chofmann/.conda/envs/detekt/share/gdal
PROJ       : 8.0.1
PROJ data dir: /home/chofmann/.conda/envs/detekt/share/proj

PYTHON DEPENDENCIES
-------------------
geopandas  : 0.10.0
pandas     : 1.3.3
fiona      : 1.8.20
numpy      : 1.21.2
shapely    : 1.7.1
rtree      : 0.9.7
pyproj     : 3.2.1
matplotlib : 3.4.3
mapclassify: 2.4.3
geopy      : None
psycopg2   : 2.9.1 (dt dec pq3 ext lo64)
geoalchemy2: 0.9.4
pyarrow    : None
pygeos     : None


</details>

BUG: fix to_postgis appending to table without CRS
Fixes bug mentioned in #2158


Discussion:
Thanks for the report!

I guess we need to adapt this check not to fail in a situation without CRS.

https://github.com/geopandas/geopandas/blob/0be92da324d6a83d2a65904cde5c983c433a1584/geopandas/io/sql.py#L420-L427

Would you like to push a PR fixing this?
Hi @martinfleis
 I created a PR that fixes the bug.
Weird... I don't really understand why `Tests / ubuntu-latest, ci/envs/37-pd10.yaml (pull_request)` failed. Is it common that this test has a timeout?
>  Is it common that this test has a timeout?

I think I've seen it couple of times before. Not common, but it happens (we should check why).

Resolving patch:
diff --git a/geopandas/io/sql.py b/geopandas/io/sql.py
--- a/geopandas/io/sql.py
+++ b/geopandas/io/sql.py
@@ -231,7 +231,7 @@ def _get_geometry_type(gdf):
 
 def _get_srid_from_crs(gdf):
     """
-    Get EPSG code from CRS if available. If not, return -1.
+    Get EPSG code from CRS if available. If not, return 0.
     """
 
     # Use geoalchemy2 default for srid
@@ -257,7 +257,7 @@ def _get_srid_from_crs(gdf):
             warnings.warn(warning_msg, UserWarning, stacklevel=2)
 
     if srid is None:
-        srid = -1
+        srid = 0
         warnings.warn(warning_msg, UserWarning, stacklevel=2)
 
     return srid


Test patch:
diff --git a/geopandas/io/tests/test_sql.py b/geopandas/io/tests/test_sql.py
--- a/geopandas/io/tests/test_sql.py
+++ b/geopandas/io/tests/test_sql.py
@@ -773,6 +773,22 @@ def test_append_with_different_crs(self, engine_postgis, df_nybb):
         with pytest.raises(ValueError, match="CRS of the target table"):
             write_postgis(df_nybb2, con=engine, name=table, if_exists="append")
 
+    @pytest.mark.parametrize("engine_postgis", POSTGIS_DRIVERS, indirect=True)
+    def test_append_without_crs(self, engine_postgis, df_nybb):
+        # This test was included in #3328 when the default value for no
+        # CRS was changed from an SRID of -1 to 0. This resolves issues
+        # of appending dataframes to postgis that have no CRS as postgis
+        # no CRS value is 0.
+        engine = engine_postgis
+        df_nybb = df_nybb.set_.crs(None, allow_override=True)
+        table = "nybb"
+
+        write_postgis(df_nybb, con=engine, name=table, if_exists="replace")
+        # append another dataframe with no crs
+
+        df_nybb2 = df_nybb
+        write_postgis(df_nybb2, con=engine, name=table, if_exists="append")
+
     @pytest.mark.parametrize("engine_postgis", POSTGIS_DRIVERS, indirect=True)
     @pytest.mark.xfail(
         compat.PANDAS_GE_20 and not compat.PANDAS_GE_202,