2012-12-27 9 views
5

Ho dati in una tupla 2D (o dire proveniente da una tabella Numpy), e la necessità di inserire in una tabella SQL. Usando Sqlalchemy Core con SQLite, come posso inserire in modo efficiente e semplice questi dati nella mia tabella?nucleo SQLAlchemy, inserire più righe da una tupla invece di dict

Prendere cioè da @eclaird;

engine = sa.create_engine('sqlite://', echo=True) 
metadata = sa.MetaData() 

widgets_table = sa.Table('widgets', metadata, 
    sa.Column('id', sa.Integer, primary_key=True), 
    sa.Column('bar', sa.String(50)), 
    sa.Column('biz', sa.Boolean), 
    sa.Column('baz', sa.Integer), 
    ) 
metadata.create_all(engine) 

# Assuming this is the data where None holds place for primary key 
my_data = [ 
    (None, "Test", True, 3), 
    (None, "Test", True, 3), 
    ] 

Finora sono al this point nella documentazione; quindi ho;

engine.execute(widgets_table.insert().values((None, "Test", True, 3))) 

Quali lavori. Ma voglio inserire molte righe contemporaneamente come

engine.execute(widgets_table.insert().values(((None, "Test", True, 3), (None, "Test", True, 3)))) 

Ma poi errore;

The 'sqlite' dialect with current database version settings does not support in-place multirow inserts.

Anche provato;

insert = widgets_table.insert() 

engine.execute(insert, [ 
        (None, "Test", True, 3), 
        (None, "Test", True, 3) 
        ]) 

Con errore;

AttributeError: 'tuple' object has no attribute 'keys'

Come un recente convertito in SQLalch, sono un po 'perso qui.

risposta

2

Ti manca qualche dettaglio sulla tua configurazione così ho fatto qualcosa. L'inserimento di tuple è difficile a meno che tu non stia inserendo anche la chiave primaria del tavolo, quindi perché non creare un dizionario dai tuoi dati prima di inserirlo?

Questo dovrebbe funzionare con SQLAlchemy 0.7.6 e versioni successive:

import sqlalchemy as sa 

engine = sa.create_engine('sqlite://', echo=True) 
metadata = sa.MetaData() 

widgets_table = sa.Table('widgets', metadata, 
    sa.Column('id', sa.Integer, primary_key=True), 
    sa.Column('foo', sa.String(50)), 
    sa.Column('bar', sa.String(50)), 
    sa.Column('biz', sa.Boolean), 
    sa.Column('baz', sa.Integer), 
    ) 
metadata.create_all(engine) 

# Assuming this is your data 
values = [ 
    (None, "Test", True, 3), 
    (None, "Test", True, 3), 
    ] 

with engine.connect() as connection: 
    with connection.begin() as transaction: 
     try: 
      markers = ','.join('?' * len(values[0])) 
      ins = 'INSERT INTO {tablename} VALUES ({markers})' 
      ins = ins.format(tablename=widgets_table.name, markers=markers) 
      connection.execute(ins, values) 
     except: 
      transaction.rollback() 
      raise 
     else: 
      transaction.commit() 
+0

Grazie, ma speravo di evitare di creare un dict temporanea - voglio evitare di dover ricordare i nomi delle colonne ovunque nel mio codice. E non è ridondante creare questo dict quando ho i dati già in tupla 2D? Ma supponiamo che conosca solo il tipo di dati e l'ordine delle colonne, c'è un modo semplice per inserirlo in modo posizionale? –

+2

avresti bisogno di usare una stringa INSERT in congiunzione con "?" per i parametri, che vengono inviati più direttamente al DBAPI pysqlite. Il costrutto insert() di SQLA tratterà sempre le cose come dizionari internamente comunque. Se la prestazione è l'obiettivo, sarebbe necessario un accesso DBAPI diretto. Se la portabilità, allora basta usare una funzione come 'dict (zip (((c.key per c in table.c), riga))' per creare il dizionario. – zzzeek

+0

modificato la mia risposta per utilizzare SQL prime, usa inserto multirow. – tuomur

Problemi correlati