automap_base
da sqlalchemy.ext.automap
(tableNamesDict è un dict con solo le tabelle Pandas):
metadata = MetaData()
metadata.reflect(db.engine, only=tableNamesDict.values())
Base = automap_base(metadata=metadata)
Base.prepare()
Che avrebbe funzionato perfettamente, ad eccezione di un problema, automap richiede le tabelle per avere una chiave primaria. Ok, nessun problema, sono sicuro che Pandas to_sql
ha un modo per indicare la chiave primaria ... no. Questo è dove ottiene un po 'hacky:
for df in dfs.keys():
cols = dfs[df].columns
cols = [str(col) for col in cols if 'id' in col.lower()]
schema = pd.io.sql.get_schema(dfs[df],df, con=db.engine, keys=cols)
db.engine.execute('DROP TABLE ' + df + ';')
db.engine.execute(schema)
dfs[df].to_sql(df,con=db.engine, index=False, if_exists='append')
ho iterare attraverso il dict
di DataFrames
, ottenere un elenco delle colonne da utilizzare per la chiave primaria (cioèquelli contenenti id
), utilizzare get_schema
per creare le tabelle vuote quindi aggiungere lo DataFrame
alla tabella.
Ora che avete i modelli, è possibile assegnare un nome in modo esplicito e utilizzarli (cioè User = Base.classes.user
) con session.query
o creare un dict di tutte le classi con qualcosa di simile:
alchemyClassDict = {}
for t in Base.classes.keys():
alchemyClassDict[t] = Base.classes[t]
E query con:
res = db.session.query(alchemyClassDict['user']).first()
@unutbu penso che il 'index = true' assicura solo l'indice viene scritto nella tabella e che è un indice in SQL, e non ancora una chiave primaria – joris
Sì, l'indice utilizza solo il numero di riga come un indice che non è quello che voglio. –
Per ora, non c'è ancora il supporto per specificare le chiavi primarie (è nella lista dei desideri delle caratteristiche). Possibile soluzione per creare prima la tabella, quindi utilizzare l'opzione 'aggiungi' in 'to_sql'. Per creare la tabella, 'pd.io.sql.get_schema' potrebbe essere utile per creare lo schema (che quindi può essere adattato/eseguito per creare la tabella) – joris