तालिका को पोस्ट करने के लिए DataFrame कैसे लिखें?


103

नहीं है DataFrame.to_sql विधि, लेकिन यह केवल mysql, SQLite और Oracle डेटाबेस के लिए काम करता है। मैं इस विधि के लिए पास नहीं कर सकता कनेक्शन या sqlalchemy इंजन पोस्टग्रेज करता है।

जवाबों:


125

पांडा 0.14 (मई 2014 के अंत में जारी) से शुरू, पोस्टग्रैस्कल समर्थित है। sqlमॉड्यूल अब का उपयोग करता है sqlalchemyविभिन्न डेटाबेस जायके का समर्थन करने के। आप एक पोस्टग्रेजल डेटाबेस ( डॉक्स देखें ) के लिए एक 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')

1
क्या इसने इसे 0.14 कर दिया?
क्वांट ऑक्ट

हां, और 0.15 भी पहले से ही जारी (जारी उम्मीदवार) है। मैं जवाब अपडेट करूंगा, पूछने के लिए धन्यवाद।
जॉरिस

1
इस पोस्ट ने मेरे लिए समस्या हल कर दी: stackoverflow.com/questions/24189150/…
srodriguex

नोट :_sql पोस्टग्रेज में सरणी प्रकार निर्यात नहीं करता है।
सौरभ साहा

1
एक नया बनाने के बजाय Sqlalchemy engine, क्या मैं उपयोग किए गए मौजूदा Postgresकनेक्शन का उपयोग कर सकता हूं psycopg2.connect()?
जार्विस

84

तेज़ विकल्प:

निम्न कोड df.to_sql विधि की तुलना में DB को तेजी से पोस्ट करने के लिए आपके पंडों DF को कॉपी करेगा और आपको df को संग्रहीत करने के लिए किसी भी मध्यवर्ती csv फ़ाइल की आवश्यकता नहीं होगी।

अपने DB विनिर्देशों के आधार पर एक इंजन बनाएं।

अपने पोस्ट DB में एक तालिका बनाएं जिसमें Dataframe (df) के समान स्तंभ हों।

DF में डेटा आपके पोस्टग्रेज टेबल में डाला जाएगा ।

from sqlalchemy import create_engine
import psycopg2 
import io

यदि आप तालिका को बदलना चाहते हैं, तो हम इसे अपने df से हेडर का उपयोग करके सामान्य to_sql विधि से बदल सकते हैं और फिर पूरे बड़े समय को df को DB में लोड कर सकते हैं।

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

@ n1000 हाँ बस contentsचर को अनदेखा करें , बाकी सब कुछ ठीक काम करना चाहिए
बॉबी

2
तुम क्यों करते हो output.seek(0)?
मोशवी

7
यह इतना तेज़ है कि यह मज़ेदार है: D
shadi

1
कुछ क्षेत्रों में नई पंक्ति वर्णों के कारण लोड टेबल मेरे लिए विफल हो रहा है। इससे मैं कैसे निपटूं? df.to_csv (आउटपुट, sep = '\ t', शीर्ष लेख = गलत, अनुक्रमणिका = गलत, एन्कोडिंग = 'utf-8') cur.copy_from (आउटपुट, 'संदेश', नल = "") "शून्य मान बन जाते हैं '' '
शंकुधारी

23

पंडों 0.24.0+ समाधान

पंडों में 0.24.0 एक नया फीचर पेश किया गया था, जिसे खासतौर पर पोस्टग्रेज के लिए तेजी से लिखा गया था। आप इसके बारे में यहाँ और जान सकते हैं: https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-sql-method

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)

3
ज्यादातर समय के लिए, method='multi'विकल्प जोड़ें काफी तेज है। लेकिन हाँ, यह COPYतरीका अभी सबसे तेज़ तरीका है।
1926

यह सीएसवी के लिए ही है? यह .xlsx के साथ भी इस्तेमाल किया जा सकता है? इसमें से प्रत्येक भाग पर कुछ नोट्स मददगार साबित होंगे। withमेमोरी बफर में लिखने के बाद पहला भाग । का अंतिम भाग withएक SQL स्टेटमेंट का उपयोग कर रहा है और डेटा को बल्क लोड करने के लिए copy_expert की गति का लाभ उठा रहा है। मध्य भाग क्या है जो करने से शुरू होता है columns =?
ड्यूडवाह जूल

इसने मेरे लिए बहुत अच्छा काम किया। और आप कृपया समारोह keysमें तर्क समझा सकते हैं psql_insert_copy? इसे कोई भी कुंजी कैसे मिलती है और क्या सिर्फ कॉलम के नाम हैं?
बोवेन लियू

मैंने इस पद्धति का उपयोग करने की कोशिश की है, हालांकि यह मुझे एक त्रुटि देता है Table 'XYZ' already exists:। जहाँ तक मैं समझता हूँ, इसे एक तालिका नहीं बनानी चाहिए?
ई। एपस्टीन

@ ई.पस्टीन - आप अंतिम पंक्ति को संशोधित कर सकते हैं df.to_sql('table_name', engine, if_exists='replace', method=psql_insert_copy)- यह आपके डेटाबेस में एक तालिका बनाता है।
mgoldwasser

21

मैंने इस तरह से इसे किया।

यह तेज़ हो सकता है क्योंकि यह उपयोग कर रहा है 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()

1
मुझे एट्रीब्यूट मिलता है: मॉड्यूल 'psycopg2' में कोई विशेषता 'एक्स्ट्रा' नहीं है। आह, यह स्पष्ट रूप से आयात करने की आवश्यकता है। आयात psycopg2.extras
GeorgeLPerkins

यह समारोह sqlalchemy समाधान
सौरभ साहा

-1

पायथन 2.7 और पंडों के लिए 0.24.2 और Psycopg2 का उपयोग कर रहे हैं

Psycopg2 कनेक्शन मॉड्यूल

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)

डेटाफ्रेम मानकर पहले से ही df के रूप में मौजूद है

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()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.