পোস্টজিআইএস টেবিলটিতে জিওপ্যান্ডস ডেটাফ্রেম যুক্ত করা হচ্ছে?


17

আমার একটি সাধারণ জিওপ্যান্ডস ডেটাফ্রেম রয়েছে:

এখানে চিত্র বর্ণনা লিখুন

আমি এই জিওডাটাফ্রেমটি একটি পোস্টজিআইএস টেবিলে আপলোড করতে চাই। পোস্টজিআইএস এক্সটেনশানটির সাথে আমার ইতিমধ্যে একটি ডেটাবেস সেটআপ আছে তবে এই ডাটাফ্রেমটিকে একটি টেবিল হিসাবে যুক্ত করার মতো মনে হচ্ছে না।

আমি নিম্নলিখিত চেষ্টা করেছি:

engine = <>
meta = MetaData(engine)
eld_test = Table('eld_test', meta, Column('id', Integer, primary_key=True), Column('key_comb_drvr', Text), 
                 Column('geometry', Geometry('Point', srid=4326))) 
eld_test.create(engine) 
conn = engine.connect() 
conn.execute(eld_test.insert(), df.to_dict('records'))

আমি নিম্নলিখিতটি চেষ্টা করেছি: ইঞ্জিন = <> # টেবিল তৈরি করুন মেটা = মেটাডেটা (ইঞ্জিন) জ্যেষ্ঠ_তম = সারণী ('জ্যেষ্ঠ_তম', মেটা, কলাম ('আইডি', পূর্ণসংখ্যা, প্রাথমিক_কি = সত্য), কলাম ('কী_কম্ব_ড্রভিআর', পাঠ্য)) , কলাম ('জ্যামিতি', জ্যামিতি ('পয়েন্ট', শ্রীড = 4326%)) জ্যেষ্ঠ_প্রেমক্রিট (ইঞ্জিন) # ডিবিপিআইয়ের এক্সিকিউটিম্যানি dicts এর সাথে সংযুক্ত = ইঞ্জিন.কনেক্ট () সংযোগ.এক্সেকিউট (জ্যেষ্ঠ_তম.সেট্রেট (), ডিএফ .to_dict ('রেকর্ডস'))
কোরআনম্যান 4:38

1
জিআইএস এসই তে স্বাগতম, আমাদের ট্যুরটি পড়ুন ! আপনি মন্তব্য পোস্ট আপনার কোড অন্তর্ভুক্ত আপনার পোস্ট সম্পাদনা করতে পারেন?
জিস্কিড 16

উত্তর:


31

পান্ডার টু_এসকিএল পদ্ধতি এবং এসকিউএলএলএকমি ব্যবহার করে আপনি পোস্টগ্র্রেসে ডেটাফ্রেম সঞ্চয় করতে পারেন। যেহেতু আপনি একটি Geodataframe সংরক্ষণ করছেন, GeoAlchemy তোমার জন্য geom কলাম হ্যান্ডেল করবে। এখানে একটি কোড নমুনা:

# Imports
from geoalchemy2 import Geometry, WKTElement
from sqlalchemy import *
import pandas as pd
import geopandas as gpd

# Creating SQLAlchemy's engine to use
engine = create_engine('postgresql://username:password@host:socket/database')


geodataframe = gpd.GeoDataFrame(pd.DataFrame.from_csv('<your dataframe source>'))
#... [do something with the geodataframe]

geodataframe['geom'] = geodataframe['geometry'].apply(lambda x: WKTElement(x.wkt, srid=<your_SRID>)

#drop the geometry column as it is now duplicative
geodataframe.drop('geometry', 1, inplace=True)

# Use 'dtype' to specify column's type
# For the geom column, we will use GeoAlchemy's type 'Geometry'
geodataframe.to_sql(table_name, engine, if_exists='append', index=False, 
                         dtype={'geom': Geometry('POINT', srid= <your_srid>)})

'If_exists' পরামিতি আপনাকে যেভাবে পোস্টফ্রেস সারণীতে ডেটাফ্রেম যুক্ত করা হবে তা হ্যান্ডেল করার অনুমতি দেয় তা লক্ষণীয়:

    if_exists = replace: If table exists, drop it, recreate it, and insert data.
    if_exists = fail: If table exists, do nothing.
    if_exists = append: If table exists, insert data. Create if does not exist.

জ্যামিতি কলামের চেয়ে আলাদা এসআরআইডি নির্দিষ্ট করে এখানে কি পুনরায় প্রজেক্ট করার সুযোগ রয়েছে বা বর্তমান এসআরআইডি ব্যবহার করতে হবে? এছাড়াও জ্যামিতি কলাম থেকে পূর্ণসংখ্যার এসআরআইডি পাওয়ার সর্বোত্তম উপায় কী ?
রোভিকো

কেন এই পদ্ধতিটি ব্যবহার করে আমার কাছে sqlalchemy.exc.In अवैधRequestError: প্রতিফলিত করা যায়নি: অনুরোধ করা টেবিল (গুলি) ইঞ্জিন ত্রুটিতে উপলব্ধ নয়?
ভিলিক

4

আপনি যে একই প্রশ্নটি জিজ্ঞাসা করেছেন এবং আমার কাছেও এটির জন্য অনেকগুলি, অনেক দিন ব্যয় করেছে (একই সাথে আমি স্বীকার করার চেয়ে বেশি যত্ন নিয়েছি) সমাধান খুঁজছি had পোস্টজিআইএস এক্সটেনশন সহ নিম্নলিখিত পোস্টগ্রাইএসকিউএল টেবিলটি ধরে নিচ্ছি,

postgres=> \d cldmatchup.geo_points;
Table "cldmatchup.geo_points"
Column   |         Type         |                               Modifiers                                
-----------+----------------------+------------------------------------------------------------------------
gridid    | bigint               | not null default nextval('cldmatchup.geo_points_gridid_seq'::regclass)
lat       | real                 | 
lon       | real                 | 
the_point | geography(Point,4326) | 

Indexes:
"geo_points_pkey" PRIMARY KEY, btree (gridid)

এই আমি শেষ পর্যন্ত কাজ পেয়েছিলাম:

import geopandas as gpd
from geoalchemy2 import Geography, Geometry
from sqlalchemy import create_engine, MetaData, Table
from sqlalchemy.orm import sessionmaker
from shapely.geometry import Point
from psycopg2.extensions import adapt, register_adapter, AsIs

# From http://initd.org/psycopg/docs/advanced.html#adapting-new-types but 
# modified to accomodate postGIS point type rather than a postgreSQL 
# point type format
def adapt_point(point):
    from psycopg2.extensions import adapt, AsIs
    x = adapt(point.x).getquoted()
    y = adapt(point.y).getquoted()
    return AsIs("'POINT (%s %s)'" % (x, y))

register_adapter(Point, adapt_point)

engine = create_engine('postgresql://<yourUserName>:postgres@localhost:5432/postgres', echo=False)
Session = sessionmaker(bind=engine)
session = Session()
meta = MetaData(engine, schema='cldmatchup')

# Create reference to pre-existing "geo_points" table in schema "cldmatchup"
geoPoints = Table('geo_points', meta, autoload=True, schema='cldmatchup', autoload_with=engine)

df = gpd.GeoDataFrame({'lat':[45.15, 35., 57.], 'lon':[-35, -150, -90.]})

# Create a shapely.geometry point 
the_point = [Point(xy) for xy in zip(df.lon, df.lat)]

# Create a GeoDataFrame specifying 'the_point' as the column with the 
# geometry data
crs = {'init': 'epsg:4326'}
geo_df = gpd.GeoDataFrame(df.copy(), crs=crs, geometry=the_point)

# Rename the geometry column to match the database table's column name.
# From https://media.readthedocs.org/pdf/geopandas/latest/geopandas.pdf,
# Section 1.2.2 p 7
geo_df = geo_df.rename(columns{'geometry':'the_point'}).set_geometry('the_point')

# Write to sql table 'geo_points'
geo_df.to_sql(geoPoints.name, engine, if_exists='append', schema='cldmatchup', index=False)

session.close()

আমি বলতে পারি না যে আমার ডাটাবেস সংযোগ যুক্তিটি সর্বোত্তম কিনা যেহেতু আমি মূলত অন্য লিঙ্ক থেকে এটি অনুলিপি করেছি এবং খুশি যে আমি জ্যামিতির সংজ্ঞাটি স্বীকৃত হয়ে আমার বিদ্যমান টেবিলটি সফলভাবে স্বয়ংক্রিয়ভাবে তৈরি করতে (বা প্রতিফলিত করতে) সক্ষম হয়েছি। আমি মাত্র কয়েক মাস ধরে স্কাইল স্পালিটাল কোডে অজগর লিখছি, তাই আমি জানি যে শিখার অনেক কিছুই রয়েছে।


0

আমার একটি সমাধান রয়েছে যার জন্য কেবল সাইকোপজি 2 এবং সুদৃ .় প্রয়োজন (অবশ্যই জিওপ্যান্ডাস ছাড়াও)। (Geo)DataFrameঅবজেক্টগুলির মাধ্যমে পুনরাবৃত্তি করা সাধারণত খারাপ অনুশীলন কারণ এটি ধীর, তবে ছোট বা এককীয়া কাজের জন্য এটি এখনও কাজটি সম্পন্ন করবে।

মূলত এটি জ্যামিতিকে অন্য কলামে ডব্লিউকেবি ফর্ম্যাটে ফেলে দিয়ে কাজ করে এবং তারপরে GEOMETRYসন্নিবেশ করার সময় এটি টাইপ করতে পুনরায় কাস্ট করে ।

নোট করুন যে আপনাকে ডান কলামগুলি সহ সময়ের আগে সারণী তৈরি করতে হবে।

import psycopg2 as pg2
from shapely.wkb import dumps as wkb_dumps
import geopandas as gpd


# Assuming you already have a GeoDataFrame called "gdf"...

# Copy the gdf if you want to keep the original intact
insert_gdf = gdf.copy()

# Make a new field containing the WKB dumped from the geometry column, then turn it into a regular 
insert_gdf["geom_wkb"] = insert_gdf["geometry"].apply(lambda x: wkb_dumps(x))

# Define an insert query which will read the WKB geometry and cast it to GEOMETRY type accordingly
insert_query = """
    INSERT INTO my_table (id, geom)
    VALUES (%(id)s, ST_GeomFromWKB(%(geom_wkb)s));
"""

# Build a list of execution parameters by iterating through the GeoDataFrame
# This is considered bad practice by the pandas community because it is slow.
params_list = [
    {
        "id": i,
        "geom_wkb": row["geom_wkb"]
    } for i, row in insert_gdf.iterrows()
]

# Connect to the database and make a cursor
conn = pg2.connect(host=<your host>, port=<your port>, dbname=<your dbname>, user=<your username>, password=<your password>)
cur = conn.cursor()

# Iterate through the list of execution parameters and apply them to an execution of the insert query
for params in params_list:
    cur.execute(insert_query, params)
conn.commit()
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.