Câu trả lời:
Bắt đầu từ pandas 0.14 (phát hành cuối tháng 5 năm 2014), postgresql được hỗ trợ. Các sql
mô-đun bây giờ sử dụng sqlalchemy
để hỗ trợ cơ sở dữ liệu hương vị khác nhau. Bạn có thể chuyển một công cụ sqlalchemy cho cơ sở dữ liệu postgresql (xem tài liệu ). Ví dụ:
from sqlalchemy import create_engine
engine = create_engine('postgresql://scott:tiger@localhost:5432/mydatabase')
df.to_sql('table_name', engine)
Bạn đúng rằng ở gấu trúc lên đến phiên bản 0.13.1 postgresql không được hỗ trợ. Nếu bạn cần sử dụng phiên bản gấu trúc cũ hơn, đây là phiên bản vá của pandas.io.sql
: https://gist.github.com/jorisvandenbossche/10841234 .
Tôi đã viết điều này một thời gian trước, vì vậy không thể đảm bảo hoàn toàn rằng nó luôn hoạt động, nhưng cơ sở nên có). Nếu bạn đặt tệp đó vào thư mục làm việc của mình và nhập nó, thì bạn sẽ có thể làm được ( con
kết nối postgresql ở đâu):
import sql # the patched version (file is named sql.py)
sql.write_frame(df, 'table_name', con, flavor='postgresql')
Sqlalchemy engine
, tôi có thể sử dụng Postgres
kết nối hiện có được tạo bằng cách sử dụng psycopg2.connect()
không?
Tùy chọn nhanh hơn:
Đoạn mã sau sẽ sao chép Pandas DF của bạn vào DB postgres nhanh hơn nhiều so với phương thức df.to_sql và bạn sẽ không cần bất kỳ tệp csv trung gian nào để lưu trữ df.
Tạo một công cụ dựa trên thông số kỹ thuật DB của bạn.
Tạo một bảng trong DB postgres của bạn có số cột bằng Dataframe (df).
Dữ liệu trong DF sẽ được chèn vào bảng postgres của bạn.
from sqlalchemy import create_engine
import psycopg2
import io
nếu bạn muốn thay thế bảng, chúng ta có thể thay thế nó bằng phương thức to_sql bình thường bằng cách sử dụng các tiêu đề từ df của chúng ta và sau đó tải toàn bộ df tốn nhiều thời gian vào 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
làm gì? Đây có nên là một trong những được viết trong copy_from()
?
contents
biến, mọi thứ khác sẽ hoạt động tốt
output.seek(0)
?
Giải pháp gấu trúc 0.24.0+
Trong Pandas 0.24.0, một tính năng mới đã được giới thiệu được thiết kế đặc biệt để ghi nhanh vào Postgres. Bạn có thể tìm hiểu thêm về nó tại đây: 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)
method='multi'
tùy chọn thêm là đủ nhanh. Nhưng có, COPY
phương pháp này là cách nhanh nhất hiện nay.
with
được ghi vào một bộ đệm trong bộ nhớ. Phần cuối cùng with
là sử dụng câu lệnh SQL và tận dụng tốc độ của copy_expert để tải dữ liệu hàng loạt. Phần giữa bắt đầu với columns =
việc làm gì?
keys
đối số trong psql_insert_copy
hàm được không? Làm thế nào nó nhận được bất kỳ khóa nào và các khóa chỉ là tên cột?
Table 'XYZ' already exists
. Theo như tôi hiểu, nó không nên tạo một bảng, phải không?
df.to_sql('table_name', engine, if_exists='replace', method=psql_insert_copy)
- điều này sẽ tạo một bảng trong cơ sở dữ liệu của bạn.
Đây là cách tôi đã làm điều đó.
Nó có thể nhanh hơn vì nó đang sử dụng 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()
Đối với Python 2.7 và Pandas 0.24.2 và sử dụng Psycopg2
Mô-đun kết nối 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
Kết nối với cơ sở dữ liệu
conn, cur = dbConnect(databaseName, dbUser, dbHost, dbPwd)
Giả sử dataframe đã có sẵn dưới dạng 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()