2017-08-18 1 views
1

Ich versuche, (mit COPY) eine große Datei von s3 nach Redshift zu schieben. Ich benutze Sqlalchemy in Python, um den SQL-Befehl auszuführen, aber es sieht aus, dass die Kopie nur funktioniert, wenn ich vorläufig die Tabelle TRUNCATE.COPY Daten von S3 zu RedShift in Python (sqlalchemy)

die Verbindung funktioniert ok:

from sqlalchemy import create_engine 
engine = create_engine('postgresql://XXXX:[email protected]:XXXX/XXXX') 

mit dieser Befehlsfolge (wenn ich die Tabelle vor dem COPY-Befehl truncate)

toRedshift = "TRUNCATE TABLE public.my_table; COPY public.my_table from 's3://XXXX/part-p.csv' CREDENTIALS 'aws_access_key_id=AAAAAAA;aws_secret_access_key=BBBBBBB' gzip removequotes IGNOREHEADER 0 delimiter '|';" 
engine.execute(toRedshift) 

Wenn ich die entfernen "TRUNCATE TABLE public.my_table;" Bit

toRedshift = "COPY public.my_table from 's3://XXXX/part-p.csv' CREDENTIALS 'aws_access_key_id=AAAAAAA;aws_secret_access_key=BBBBBBB' gzip removequotes IGNOREHEADER 0 delimiter '|';" 
engine.execute(toRedshift) 

Aber der Befehl funktioniert perfekt mit jedem anderen SQL-Client (wie DBeaver zum Beispiel)

+1

Ziemlich sicher, dass dies kommt auf [wie autocommit Werke] (http://docs.sqlalchemy.org/en/latest/core/connections.html#understanding-autocommit), aber noch nicht sicher, wie oder wenn überhaupt. Weder TRUNCATE noch COPY sind im AUTOCOMMIT_REGEXP-Muster aufgeführt. Versuchen Sie, Ihre ''COPY ...' 'Anweisung in ein' text (stmt) .execution_options (autocommit = True) 'Konstrukt zu schreiben und übergeben Sie dieses an' engine.execute() '. –

+0

engine.execute (text (stmt). Execution_options (autocommit = True)) – user3620915

Antwort

0

Danke Ilja. Mit diesem Befehl funktioniert es:

engine.execute(text(toRedshift).execution_options(autocommit=True)) 

Ich weiß nicht, warum ich in der Lage war, die Daten mit dem TRUNCATE Bit schiebt an der Vorderseite des Strings.

Ivan

+0

Aus unbekannten Gründen löst es den Autocommit (oder so scheint es), obwohl, wie ich schon sagte, zumindest das aktuelle Regexp-Muster für Postgresql nicht hat TRUNCATE: https://github.com/zzzeek/sqlalchemy/blob/master/lib/sqlalchemy/dialects/postgresql/base.py#L892 –

+0

Ich denke, in den meisten DB TRUNCATE ist DDL-Befehl, nicht DML (siehe https: // stackoverflow.com/questions/2578194/what-is-ddl-and-dml). DDL-Befehle lösen Commit inhärent aus. – Dolfa

+1

@dolfa SQLA behandelt spezifisch "autocommit" selbst, mit einer Regex-Übereinstimmung mit der ausgegebenen Anweisung (oder Anweisungen, obwohl SQLA offiziell keine Multi-Anweisung SQL unterstützt, wie [in diesem sehr ähnlichen Beitrag] (https: // stackoverflow. com/questions/45347565/Ausführen mehrerer Anweisungen mit postgresql-via-sqlalchemy-does-not-persist-ch)). Diese Regex enthält auch ddl: create, alter, etc., aber nicht abgeschnitten. –

Verwandte Themen