পোস্টগ্রিস টেবিলে ডেটাফ্রেম কীভাবে লিখবেন?


109

নেই DataFrame.to_sql পদ্ধতি, কিন্তু এটি শুধুমাত্র মাইএসকিউএল, SQLite এবং ওরাকল ডাটাবেস জন্য কাজ করে। আমি এই পদ্ধতিটি পোস্টগ্রিস কানেকশন বা স্কেলচেমি ইঞ্জিনে পাস করতে পারি না।

উত্তর:


131

পান্ডাস 0.14 (মে 2014 এর শেষের দিকে প্রকাশিত) থেকে শুরু করে পোস্টগ্রেস্কল সমর্থিত। sqlমডিউল এখন ব্যবহার sqlalchemyবিভিন্ন ডাটাবেসের স্বাদে সমর্থন। আপনি একটি পোস্টগ্রেএসকিএল ডাটাবেসের জন্য স্ক্যালকিমি ইঞ্জিনটি পাস করতে পারেন ( দস্তাবেজগুলি দেখুন )। যেমন:

from sqlalchemy import create_engine
engine = create_engine('postgresql://scott:tiger@localhost:5432/mydatabase')
df.to_sql('table_name', engine)

আপনি ঠিক বলেছেন যে 0.13.1 সংস্করণ পর্যন্ত পান্ডাগুলিতে পোস্টগ্র্যাস্কেল সমর্থনযোগ্য ছিল না। আপনার যদি পান্ডার পুরোনো সংস্করণটি ব্যবহার করতে হয় তবে এখানে একটি প্যাচযুক্ত সংস্করণ রয়েছে pandas.io.sql: https://gist.github.com/jorisvandenbossche/10841234
আমি এটি একটি সময় আগে লিখেছিলাম, সুতরাং এটি সর্বদা কার্যকরভাবে গ্যারান্টি দিতে পারে না, তবে ভিত্তিটি সেখানে হওয়া উচিত)। যদি আপনি সেই ফাইলটিকে আপনার কার্যনির্বাহী ডিরেক্টরিতে রাখেন এবং এটি আমদানি করেন, তবে আপনার করতে সক্ষম হওয়া উচিত ( conপোস্টগ্রিস্কল সংযোগটি কোথায় ):

import sql  # the patched version (file is named sql.py)
sql.write_frame(df, 'table_name', con, flavor='postgresql')

4
এটি কি এটি 0.14 এ তৈরি করেছে?
কোয়ান্ট

হ্যাঁ, এবং এছাড়াও 0.15 ইতিমধ্যে মুক্তি পেয়েছে (মুক্তি প্রার্থী)। আমি উত্তর আপডেট করব, জিজ্ঞাসা করার জন্য ধন্যবাদ।
জরিস

4
: এই পোস্টটি আমার জন্য সমস্যার সমাধান stackoverflow.com/questions/24189150/...
srodriguex

দ্রষ্টব্য: to_sql পোস্টগ্রিতে অ্যারে প্রকারগুলি রফতানি করে না।
সৌরভ সাহা

4
নতুন তৈরি করার পরিবর্তে Sqlalchemy engine, আমি কি ব্যবহার Postgresকরে তৈরি একটি বিদ্যমান সংযোগ ব্যবহার করতে পারি psycopg2.connect()?
আন্ডারওস

92

দ্রুত বিকল্প:

নিম্নলিখিত কোডটি আপনার পান্ডাস ডিএফ কে df.to_sql পদ্ধতির চেয়ে দ্রুত ডিগ্রি পোস্টগ্রিজে কপি করবে এবং ডিএফ সঞ্চয় করার জন্য আপনার কোনও মধ্যবর্তী সিএসভি ফাইলের প্রয়োজন হবে না।

আপনার ডিবি নির্দিষ্টকরণের উপর ভিত্তি করে একটি ইঞ্জিন তৈরি করুন।

আপনার পোস্টগ্রিজ ডিবিতে একটি টেবিল তৈরি করুন যাতে সমান সংখ্যক কলামের ডেটাফ্রেম (ডিএফ) থাকে।

ডিএফ-তে থাকা ডেটা আপনার পোস্টগ্রিজে সারণিতে প্রবেশ করানো হবে ।

from sqlalchemy import create_engine
import psycopg2 
import io

আপনি যদি টেবিলটি প্রতিস্থাপন করতে চান তবে আমরা আমাদের ডিএফ থেকে শিরোনাম ব্যবহার করে এটি সাধারণ টু_এসকিউএল পদ্ধতিতে প্রতিস্থাপন করতে পারি এবং তারপরে পুরো বড় সময় গ্রাসকারী ডিএফকে ডিবিতে লোড করতে পারি।

engine = create_engine('postgresql+psycopg2://username:password@host:port/database')

df.head(0).to_sql('table_name', engine, if_exists='replace',index=False) #truncates the table

conn = engine.raw_connection()
cur = conn.cursor()
output = io.StringIO()
df.to_csv(output, sep='\t', header=False, index=False)
output.seek(0)
contents = output.getvalue()
cur.copy_from(output, 'table_name', null="") # null values become ''
conn.commit()

ভেরিয়েবল কী করে contents? এই লিখিত হয় এক হতে হবে copy_from()?
n1000

4
তুমি কেন করো output.seek(0)?
মোশেভি

10
এটি এত দ্রুত যে এটি মজাদার: D
shadi

4
কিছু ক্ষেত্রের নতুন লাইন অক্ষরের কারণে লোড টেবিলটি আমার জন্য ব্যর্থ হচ্ছে। আমি কীভাবে এটি পরিচালনা করব? df.to_csv (আউটপুট, sep = '\ t', শিরোনাম = মিথ্যা, সূচক = মিথ্যা, এনকোডিং = 'utf-8') cur.copy_from (আউটপুট, 'বার্তা', নাল = "") # নাল মান হয়ে যায় ''
কনেটফুন

4
@ মোশেভী - সন্ধান পদ্ধতিটি ফাইলের বর্তমান অবস্থান নির্ধারণ করে, সুতরাং এখানে এটি স্পষ্টভাবে ফাইলের শুরুতে অবস্থানটি সরিয়ে নিয়ে যাচ্ছে, 0 বাইট / প্যাথন
ডকস /

26

পান্ডাস 0.24.0+ সমাধান

পান্ডাস ০.২৪.০-তে একটি নতুন বৈশিষ্ট্য প্রবর্তিত হয়েছিল যা পোস্টগ্র্রেসে দ্রুত লেখার জন্য বিশেষভাবে ডিজাইন করা হয়েছিল। আপনি এটি সম্পর্কে এখানে আরও জানতে পারেন: https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-sql- আদর্শ

import csv
from io import StringIO

from sqlalchemy import create_engine

def psql_insert_copy(table, conn, keys, data_iter):
    # gets a DBAPI connection that can provide a cursor
    dbapi_conn = conn.connection
    with dbapi_conn.cursor() as cur:
        s_buf = StringIO()
        writer = csv.writer(s_buf)
        writer.writerows(data_iter)
        s_buf.seek(0)

        columns = ', '.join('"{}"'.format(k) for k in keys)
        if table.schema:
            table_name = '{}.{}'.format(table.schema, table.name)
        else:
            table_name = table.name

        sql = 'COPY {} ({}) FROM STDIN WITH CSV'.format(
            table_name, columns)
        cur.copy_expert(sql=sql, file=s_buf)

engine = create_engine('postgresql://myusername:mypassword@myhost:5432/mydatabase')
df.to_sql('table_name', engine, method=psql_insert_copy)

4
বেশিরভাগ সময়, অ্যাড method='multi'বিকল্পটি যথেষ্ট দ্রুত। তবে হ্যাঁ, এই COPYপদ্ধতিটি এখনই সবচেয়ে দ্রুততম উপায়।
ssword

এটি কি কেবল সিএসভির জন্য? এটিও .xlsx এর সাথেও ব্যবহার করা যেতে পারে? এর প্রতিটি অংশ কী করছে সে সম্পর্কে কিছু নোট সহায়ক হবে। এর পরে প্রথম অংশটি withমেমরি বাফারে লিখছে। এর শেষ অংশটি withএসকিউএল স্টেটমেন্ট ব্যবহার করে এবং কপি_এক্সপার্টের গতির সুবিধা গ্রহণ করে ডেটা লোকে লোড করে। মধ্যম অংশটি কী শুরু করে যা শুরু columns =করে?
ডুডাহা

এটি আমার পক্ষে খুব ভাল কাজ করেছে। এবং আপনি ফাংশন keysমধ্যে যুক্তি ব্যাখ্যা করতে পারেন psql_insert_copyদয়া করে? এটি কী কীভাবে পায় এবং কীগুলি কেবল কলামের নাম?
বোভেন লিউ

আমি এই পদ্ধতি ব্যবহার করে চেষ্টা করেছি, কিন্তু এটা আমার একটি ত্রুটি ছোঁড়া: Table 'XYZ' already exists। আমি যতদূর বুঝতে পারি, এটি একটি টেবিল তৈরি করা উচিত নয়, এটি করা উচিত?
E.Epstein

@ E.Epstein - আপনি শেষ লাইনটি সংশোধন করতে পারেন df.to_sql('table_name', engine, if_exists='replace', method=psql_insert_copy)- এটি আপনার ডাটাবেসে একটি সারণী তৈরি করে।
মিগলডওয়েসার

24

এইভাবে আমি এটি করেছি।

এটি আরও দ্রুত হতে পারে কারণ এটি ব্যবহার করছে execute_batch:

# df is the dataframe
if len(df) > 0:
    df_columns = list(df)
    # create (col1,col2,...)
    columns = ",".join(df_columns)

    # create VALUES('%s', '%s",...) one '%s' per column
    values = "VALUES({})".format(",".join(["%s" for _ in df_columns])) 

    #create INSERT INTO table (columns) VALUES('%s',...)
    insert_stmt = "INSERT INTO {} ({}) {}".format(table,columns,values)

    cur = conn.cursor()
    psycopg2.extras.execute_batch(cur, insert_stmt, df.values)
    conn.commit()
    cur.close()

4
আমি অ্যাট্রিবিউটআরার পেয়েছি: মডিউল 'সাইকোপজি 2' এর কোনও 'এক্সট্রা' নেই। আহ, এটিকে সুস্পষ্টভাবে আমদানি করা দরকার। psycopg2.extras আমদানি করুন
জর্জএলপারকিনস

এই ফাংশনটি স্ক্যালকিমি সমাধানের চেয়ে অনেক দ্রুত
সৌরভ সাহা

-1

পাইথন ২.7 এবং পান্ডাসের জন্য 0.24.2 এবং সাইকোপজি 2 ব্যবহার করে

সাইকোপজি 2 সংযোগ মডিউল

def dbConnect (db_parm, username_parm, host_parm, pw_parm):
    # Parse in connection information
    credentials = {'host': host_parm, 'database': db_parm, 'user': username_parm, 'password': pw_parm}
    conn = psycopg2.connect(**credentials)
    conn.autocommit = True  # auto-commit each entry to the database
    conn.cursor_factory = RealDictCursor
    cur = conn.cursor()
    print ("Connected Successfully to DB: " + str(db_parm) + "@" + str(host_parm))
    return conn, cur

ডাটাবেসের সাথে সংযুক্ত করুন

conn, cur = dbConnect(databaseName, dbUser, dbHost, dbPwd)

ডিএফ হিসাবে ইতিমধ্যে উপস্থিত হতে ডেটাফ্রেম ধরে নিচ্ছি

output = io.BytesIO() # For Python3 use StringIO
df.to_csv(output, sep='\t', header=True, index=False)
output.seek(0) # Required for rewinding the String object
copy_query = "COPY mem_info FROM STDOUT csv DELIMITER '\t' NULL ''  ESCAPE '\\' HEADER "  # Replace your table name in place of mem_info
cur.copy_expert(copy_query, output)
conn.commit()
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.