python Connection中的复制即式.执行:CSV进入Postgres-没有错误,但也没有数据



我正在尝试将数据从CSV加载到我的Postgres数据库。我正在使用sqlalchemy(以及连接/RAW SQL数据方法而不是ORM方法(。但是,我在各个字段中成功创建了我的桌子。当使用复印件时,什么也不会发生:我没有出错,但我的表格也为空。

conn = eng.connect()
trans = conn.begin()
try: 
    conn.execute("""CREATE TABLE IF NOT EXISTS table_name(var1 numeric, date date, time time, datetime timestamp primary key,....);""")
    trans.commit()
except:
    trans.rollback()
    raise
try: 
    # File 1 bid
    conn.execute("""COPY table_name FROM '/home/user/csvfile.csv' 
    WITH CSV HEADER DELIMITER as ','""")
    trans.commit()
except:
    trans.rollback()
    raise

jupyter笔记本中没有报告错误消息。

我在做什么错?

此外,我不太了解:

file = "/home/user/csvfile.csv"
  conn.execute("""COPY table_name FROM file 
        WITH CSV HEADER DELIMITER as ','""")

在"文件"中产生错误。

交易无法重复使用:

>>> trans = conn.begin()
2018-03-29 09:14:33,001 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
>>> trans.commit()
2018-03-29 09:14:35,449 INFO sqlalchemy.engine.base.Engine COMMIT
>>> trans.commit()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/u/sqlalchemy/lib/sqlalchemy/engine/base.py", line 1642, in commit
    raise exc.InvalidRequestError("This transaction is inactive")
sqlalchemy.exc.InvalidRequestError: This transaction is inactive
>>> trans.rollback()
>>> 

您必须在第一个交易之后启动新事务,或在同一交易中执行所有操作。

另一方面,这不能解释您的副本失败的原因。在先前的显式交易结束后,连接又回到了自动加入。如果没有进行交易,请换一种引擎或连接的方式。但这是捕获:自动企业基于检测数据更改操作,这是通过将给定语句与

匹配来完成的
AUTOCOMMIT_REGEXP = re.compile(
    r's*(?:UPDATE|INSERT|CREATE|DELETE|DROP|ALTER|GRANT|REVOKE|'
    'IMPORT FOREIGN SCHEMA|REFRESH MATERIALIZED VIEW|TRUNCATE)',
    re.I | re.UNICODE)

您可能会注意到,副本不是该正则是该正则的一部分。如前所述,您最好的选择是开始另一笔明确的交易,或在同一交易中执行这两个措施。但是,如果您希望将来使用AutoCompit使用副本,请指示SQLalchemy应该自动加入:

conn.execute(text("COPY ...").execution_options(autocommit=True))

关于后一个错误,FROM file无法神奇地访问Python变量,并且是语法错误。将文件名作为参数传递给查询:

copy_stmt = text("COPY table_name FROM :file WITH CSV HEADER")
copy_stmt = copy_stmt.execution_options(autocommit=True)
conn.execute(copy_stmt, {"file": file})

请注意,从文件中复制需要您可能不应该有的特权:

复制命名文件或命令仅允许到数据库超级用户,因为它允许读取或编写服务器具有特权访问的任何文件。

解决方案是使用COPY ... FROM STDIN,但是要使用必须使用RAW DB-API连接:

file = "/home/user/csvfile.csv"
stmt = "COPY table_name FROM STDIN CSV HEADER"
raw_conn = eng.raw_connection()
# Uses the actual psycopg2 connection as a context manager
# for transaction handling.
with open(file) as f, 
        raw_conn.connection, 
        raw_conn.cursor() as cur:
    cur.copy_expert(stmt, f)
raw_conn.close()

尝试添加";"到您的复制命令。...定界符','CSV;": - (

最新更新