2015-11-03 18 views
21

Ho un notebook ipython con celle miste markdown e python.Leggere il contenuto della cella in un notebook ipython

E vorrei che alcune delle mie celle python leggessero le celle adiacenti markdown e le elaborassero come input.

Un esempio della situazione desiderata:

CELL 1 (markdown): codice SQL per eseguire

CELL 2 (markdown): select * from tbl where x=1

CELL 3 (python): mysql.query(ipython.previous_cell.content)

(La sintassi ipython.previous_cell.content si compone)

esecuzione "CELL 3" dovrebbe essere equivalente a mysql.query("select * from tbl where x=1")

Come si può fare?

+1

Vorrei iniziare chiedendo "Questo può essere fatto?". Non penso che questo sia ovvio. – cel

+0

In un modo o nell'altro è sempre possibile provare a interpretare il formato '.ipynb' e leggere il contenuto della cella –

+1

Posso chiedere, cosa stai cercando di ottenere con questo? –

risposta

13

Penso che tu stia cercando di attaccare il problema nel modo sbagliato.

Prima sì, è possibile ottenere la cella di markdown adiacente in modo davvero stravagante che non funzionerebbe con l'esecuzione headless del notebook.

Quello che si vuole fare è usare le magie delle celle IPython, che consentono una sintassi arbitraria a condizione che la cella inizi con i segni del 2% seguiti da un identificatore.

In genere si desiderano celle SQL.

È possibile fare riferimento alla documentazione su cells magics o posso mostrarvi come costruire che:

from IPython.core.magic import (
    Magics, magics_class, cell_magic, line_magic 
) 

@magics_class 
class StoreSQL(Magics): 


    def __init__(self, shell=None, **kwargs): 
     super().__init__(shell=shell, **kwargs) 
     self._store = [] 
     # inject our store in user availlable namespace under __mystore 
     # name 
     shell.user_ns['__mystore'] = self._store 

    @cell_magic 
    def sql(self, line, cell): 
     """store the cell in the store""" 
     self._store.append(cell) 

    @line_magic 
    def showsql(self, line): 
     """show all recorded statements""" 
     print(self._store) 

    ## use ipython load_ext mechanisme here if distributed 
    get_ipython().register_magics(StoreSQL) 

Ora è possibile utilizzare la sintassi SQL nelle vostre cellule pitone:

%%sql 
select * from foo Where QUX Bar 

un secondo cell:

%%sql 
Insert Cheezburger into Can_I_HAZ 

controllare cosa abbiamo eseguito (il 3 dashe s mostrano la delimitazione di ingresso/uscita, non c'è bisogno di digitare loro):

%showsql 
--- 
['select * from foo Where QUX Bar', 'Insert Cheezburger into Can_I_HAZ'] 

E quello che hai chiesto, all'inizio della tua domanda:

mysql.query(__mystore[-1]) 

Questo naturalmente richiede che si esegue le celle precedenti nell'ordine corretto, nulla ti impedisce di utilizzare la sintassi %%sql per denominare le tue celle, ad esempio se _store è un dict, o meglio una classe in cui si sovrascrive __getattr__, per agire come __getitem__ per accedere ai campi con la sintassi del punto.Questo è lasciato come esercizio per il lettore, o vedere fine della risposta:

@cell_magic 
def sql(self, line, cell): 
    """store the cell in the store""" 
    self._store[line.strip()] = cell 

è possibile utilizzare cellule SQL come

%%sql A1 
set foo TO Bar where ID=9 

E poi nelle vostre cellule Python

mysql.execute(__mystore.A1) 

Vorrei anche suggerire caldamente Catherine Develin SqlMagic per IPython, e questo Notebook gist su GitHub che mostra tutto ciò che è vivo.

Nel commento, sembra che tu voglia aggiungere pig, nulla ti impedisce di avere una magia %%pig neanche. È anche possibile iniettare Javascript per abilitare l'evidenziazione sintattica corretta di SQL e PIG, ma questo va oltre lo scopo di questa domanda.

+0

Non ho bisogno di questa particolare soluzione, ma questa è una grande informazione sulle magie IPython, grazie! – alexis

Problemi correlati