2015-12-10 25 views

Odpowiedz

5

Model DataFrame.to_sql() korzysta z wbudowanej pandy pandas.io.sql package, która sama polega na SQLAlchemy jako warstwie abstrakcji bazy danych. W celu stworzenia „tymczasowy” w tabeli SQLAlchemy ORM, you need to supply a prefix:

t = Table(
    't', metadata, 
    Column('id', Integer, primary_key=True), 
    # ... 
    prefixes=['TEMPORARY'], 
) 

Z tego co widzę, pandas.io.sqldoes not allow you to specify the prefixes lub łatwo zmienić sposób tabele są tworzone.

Jednym ze sposobów podejścia do tego problemu byłoby utworzyć tabelę tymczasową wcześniej i używać to_sql() z if_exists="append" (wszystko przy użyciu tego samego połączenia z bazą danych).


Oto również co próbowałem zrobić: przesłonić _create_table_setup() metodę, pandas.io.sql.SQLTable „s i przekazać prefixes do konstruktora Table. Z jakiegoś powodu tabela nadal była tworzona jako tymczasowa. Nie jestem pewien, czy to by pomogło, ale tutaj jest kod, którego używałem: gist. Jest to trochę hacky, ale mam nadzieję, że byłby to przynajmniej przykładowy kod, który pozwoliłby ci zacząć to podejście.

+1

Funkcja '_create_table_setup' jest wywoływana tylko w' __init__', aby ustawić właściwość 'table'. Aby utworzyć tabelę z 'pandas.io.sql.SQLTable', wywołujesz' create', który wywołuje '_execute_create', który nadpisuje właściwość' table'. Dlatego twoja próba nie zadziałała. Zamiast tego musisz edytować "_execute_create": https://gist.github.com/alecxe/44682f79b18f0c82a99c#gistcomment-2359365 –

0

Może to być trochę hackowate i nie tworzy on technicznie tabeli tymczasowej, po prostu działa jak jeden, ale można utworzyć, korzystając z @contextmanager decorator from contextlib, aby utworzyć tabelę po otwarciu kontekstu i upuścić go z bliska. Mogło wyglądać mniej więcej:

from contextlib import contextmanager 

import numpy as np 
import sqlalchemy as sqla 
import pandas as pd 


@contextmanager 
def temp_table(frame, tbl, eng, *args, **kwargs): 
    frame.to_sql(tbl, eng, *args, **kwargs) 
    yield 
    eng.execute('DROP TABLE {}'.format(tbl)) 

df = pd.DataFrame(np.random.randint(21, size=(10, 10))) 
cnx = sqla.create_engine(conn_string) 

with temp_table(df, 'some_table_name', cnx, if_exists='replace', flavor='mysql', index=False): 
    # do stuff with "some_table_name" 

Przetestowałem go za pomocą Teradata i działa dobrze. Nie mam kodem MySQL, na którym mogę go przetestować, ale tak długo jak instrukcje DROP działają w MySQL, powinien działać tak, jak powinien.