NEWS
sql daten exportieren
-
Hallo
ich möchte alle Daten (Stromzählerwerte) aus dem sql(sqliteDB) in ein csv exportieren. Der Adapter hat zwar eine Exportfunktion aber die exportiert nur 500 Datensätze. Einstellungen um diese Grenze zu überspringen konnte ich leider nicht finden. Welchen Weg gibt es?
Danke
-
Eigentlich hasse ich die Antwort ja.
Aber gefühlt sind die ersten 10 Google-Treffer von "sqlite csv Export" die Lösung. -
ja schon, ich dachte das es in IObroker etwas passendes geben würde anstatt mich mit einem SQLite explorer direkt auf die Datenbank zu klinken. Schade.
Viele Grüße
-
Gibt's ja evtl.
Weiß es aber auch nicht. -
@darth probiere mal, dauert aber mit SQLITE etwas
/** * Zweck: Exportiert History Daten in eine CSV, wandelt optional in Exceldatum incl. Sommer- und Winterzeit * Datum: 19.07.2022 * Autor: @fastfoot */ const fileName = '/opt/iobroker/ts_number.csv'; const exportForExcel = false; //wenn true wird in ein Excel Datum gewandelt() sendTo('sql.0', 'query', 'select * from ts_number', r => { jsonToCSV(r.result, fileName) log('done!', 'warn') }) //converts a JSON table to csv file function jsonToCSV(records, fileName) { const fs = require('fs'); const CRLF = '\r\n'; const DELIM = ';'; const TXTQUAL = '"'; let csv = Object.keys(records[0]).slice().join(DELIM) + CRLF; for (let record of records) { for (let rec of Object.keys(record)) { if (typeof record[rec] == 'number') { if (exportForExcel && rec === 'ts') { const ts = record[rec]; const dst = isDST(ts); if (dst) { record[rec] = ts / 864e5 + 25569 + 2 / 24; } else { record[rec] = ts / 864e5 + 25569 + 1 / 24; } } csv += record[rec].toString().replace('.', ',') + DELIM; } else { csv += TXTQUAL + record[rec] + TXTQUAL + DELIM; } } csv += CRLF; } fs.writeFile(fileName, csv, err => { if (err) console.log(err); }) } //berechnet ob Sommer- oder Winterzeit(letzter Sonntag im März und letzter Sonntag im Novemver!!!) function isDST(ts) { const dat = new Date(ts); const y = dat.getFullYear(); const ls1 = new Date(y, 3, 1); const ls2 = new Date(y, 11, 1); ls1.getDay() > 0 ? ls1.setDate(ls1.getDate() - 7 + (7 - ls1.getDay())) : ls1.setDate(ls1.getDate() - 7); ls2.getDay() > 0 ? ls2.setDate(ls2.getDate() - 7 + (7 - ls2.getDay())) : ls2.setDate(ls2.getDate() - 7); ls1.setHours(3, 0, 0, 0); ls2.setHours(3, 0, 0, 0); return dat >= ls1 && dat <= ls2; }
-
ok danke erstmal. Wo führt man dieses Skript aus, einfach als neues Script unter Scripte oder als bash script auf der Konsole des PI?
-
@darth anhand des
sendTo
im Scripte würde ich sagen unter Scripte als JS-Script -
@fastfoot sagte in sql daten exportieren:
select * from ts_number
als sql würde ich das hier vorschlagen
select dp.name,val.ts,val.val,val.ack,val.q from ts_number as val, datapoints as dp where val.id=dp.id
sonst kann man die datenpunktbezeichnungen schlecht lesen.
sqlite hat selbst auch einen modus um csv dateien zu schreiben.
https://stackoverflow.com/questions/6076984/sqlite-how-do-i-save-the-result-of-a-query-as-a-csv-file
das dürfte schneller gehen, muss man dann aber als bash befehl aufrufen. -
@fastfoot
Der Script wirft bei mir leider eine Warnung:16:09:47.731 warn javascript.0 (303078) TypeError: Cannot read property '0' of undefined at jsonToCSV (script.js.diverse_Exports.Export_Gaszaehler:22:34) at Object.cb (script.js.diverse_Exports.Export_Gaszaehler:12:5) at change (/opt/iobroker/node_modules/iobroker.js-controller/lib/adapter.js:5620:71) at Immediate._onImmediate (/opt/iobroker/node_modules/@iobroker/db-states-redis/lib/states/statesInRedisClient.js:232:37) at processImmediate (internal/timers.js:464:21)
Hab ich das was übersehen? Oder geht er trotzdem und ich muss nur sehr sehr lange warten bis das Ergebnisfile kommt (es wurde kein File im Zielordner angelegt)
Gruß
Thomas.