它看起来像Psycopg具有用于执行自定义命令COPY :
使用cursor.copy_from()psycopg2 COPY较大输入冻结
有没有从SQLAlchemy的访问此功能的方法吗?
它看起来像Psycopg具有用于执行自定义命令COPY :
使用cursor.copy_from()psycopg2 COPY较大输入冻结
有没有从SQLAlchemy的访问此功能的方法吗?
它看起来并不像它 。
您可能只使用psycopg2揭露此功能,并放弃了ORM功能。 我想我真的不明白ORM的好处在这样的操作呢,因为它是一个直BULK INSERT和处理单个对象一拉一个ORM不会真的做了一大堆的道理。
接受的答案是正确的,但如果你想不仅仅是EoghanM的评论多了去了,在接下来的在复制一个表出来,以CSV为我工作...
from sqlalchemy import sessionmaker, create_engine
eng = create_engine("postgresql://user:pwd@host:5432/db")
ses = sessionmaker(bind=engine)
dbcopy_f = open('/tmp/some_table_copy.csv','wb')
copy_sql = 'COPY some_table TO STDOUT WITH CSV HEADER'
fake_conn = eng.raw_connection()
fake_cur = fake_conn.cursor()
fake_cur.copy_expert(copy_sql, dbcopy_f)
该sessionmaker
是没有必要的,但如果你在同一时间创造的发动机和会话的习惯是使用raw_connection
你需要将它们分开(除非有某种方式,通过会话对象访问引擎,我不知道)。 提供的SQL字符串copy_expert
也没有给它的唯一的方式,有一个基本的copy_to
,您可以使用,你可以过去的正常参数的子集使用功能COPY
TO查询。 该命令的整体表现似乎快给我,抄写〜20000行的表。
http://initd.org/psycopg/docs/cursor.html#cursor.copy_to http://docs.sqlalchemy.org/en/latest/core/connections.html#sqlalchemy.engine.Engine.raw_connection
如果您的发动机配置了psycopg2连接字符串(这是默认的,所以无论是"postgresql://..."
或"postgresql+psycopg2://..."
),你可以创建一个psycopg2光标从SQL使用炼金术会议
cursor = session.connection().connection.cursor()
你可以用它来执行
cursor.copy_from(...)
光标将活跃在相同的事务中会话目前是。 如果commit
或rollback
发生时,任何进一步的使用光标抛出的psycopg2.InterfaceError
,你必须创建一个新的。
您可以使用:
def to_sql(engine, df, table, if_exists='fail', sep='\t', encoding='utf8'):
# Create Table
df[:0].to_sql(table, engine, if_exists=if_exists)
# Prepare data
output = cStringIO.StringIO()
df.to_csv(output, sep=sep, header=False, encoding=encoding)
output.seek(0)
# Insert data
connection = engine.raw_connection()
cursor = connection.cursor()
cursor.copy_from(output, table, sep=sep, null='')
connection.commit()
cursor.close()
我插入200000线在5秒内,而不是在4分钟
你并不需要下降到psycopg2,使用raw_connection也不光标。
刚刚执行的SQL像往常一样,你甚至可以使用带有绑定参数text()
engine.execute(text('''copy some_table from :csv
delimiter ',' csv'''
).execution_options(autocommit=True),
csv='/tmp/a.csv')
您可以删除execution_options(autocommit=True)
如果这个PR将被接受
如果你能得到的引擎,你拥有所有你需要做的是:
engine = create_engine('postgresql+psycopg2://myuser:password@localhost/mydb')
# or
engine = session.engine
# or any other way you know to get to the engine
现在,你可以工作。
# isolate a connection
connection = engine.connect().connection
# get the cursor
cursor = connection.cursor()
这里有一些模板的COPY语句来使用cursor.copy_expert()
比一个更完整,更灵活的选择copy_from()
或copy_to()
因为它是在此间表示: http://initd.org/psycopg/docs/cursor的.html#cursor.copy_expert 。
# to dump to a file
dump_to = """
COPY mytable
TO STDOUT
WITH (
FORMAT CSV,
DELIMITER ',',
HEADER
);
"""
# to copy from a file:
copy_from = """
COPY mytable
FROM STDIN
WITH (
FORMAT CSV,
DELIMITER ',',
HEADER
);
"""
查看一下上述选项的含义和其他可能会感兴趣的您的具体情况https://www.postgresql.org/docs/current/static/sql-copy.html 。
重要说明:链接的文档cursor.copy_expert()
指示要使用STDOUT写出来到一个文件,STDIN从文件复制。 但是,如果你看一下在PostgreSQL的手册中的语法,你会发现,你还可以指定写入或直接在COPY语句文件。 不这样做,你可能只是浪费你的时间,如果你不是root运行(谁在开发过程中运行Python作为根?)只是做什么在psycopg2的文档显示,并与您的语句中指定STDIN或STDOUT cursor.copy_expert()
它应该是罚款。
# running the copy statement
with open('/path/to/your/data/file.csv') as f:
cursor.copy_expert(copy_from, file=f)
# don't forget to commit the changes.
connection.commit()