2016-07-29 18 views
1

Ich bin neu in Deedle, und in der Dokumentation kann ich nicht finden, wie man mein Problem löst.Deedle Frame von der Datenbank, was ist das Schema?

ich eine SQL-Tabelle zu einem Deedle Rahmen binden den folgenden Code:

namespace teste 

open FSharp.Data.Sql 
open Deedle 
open System.Linq 

module DatabaseService = 

    [<Literal>] 
    let connectionString = "Data Source=*********;Initial Catalog=*******;Persist Security Info=True;User ID=sa;Password=****"; 

    type bd = SqlDataProvider< 
       ConnectionString = connectionString, 
       DatabaseVendor = Common.DatabaseProviderTypes.MSSQLSERVER > 

    type Database() = 

     static member contextDbo() = 
      bd.GetDataContext().Dbo 

     static member acAgregations() = 
      Database.contextDbo().AcAgregations |> Frame.ofRecords 

     static member acBusyHourDefinition() = 
      Database.contextDbo().AcBusyHourDefinition 
      |> Frame.ofRecords "alternative_reference_table_scan", "formula"] 

     static member acBusyHourDefinitionFilterByTimeAgregationTipe(value:int) = 
      Database.acBusyHourDefinition() 
      |> Frame.getRows 

Diese Dinge richtig funktionieren becuse ich nicht den Datenrahmen Schema verstehen kann, für meine Überraschung ist dies nicht eine Darstellung des Tisches.

Meine Frage ist:

wie kann ich meine Datenbankelemente von Zeilen zuzugreifen statt Spalten (Spalten ist der Deedle Standard)? Ich Thied, was in der Dokumentation gezeigt wird, aber unglücklicherweise werden die Spaltennamen nicht erkannt, wie in the CSV example in Deedle Website.

+0

Sie haben also den SQL Server mit dem Typ Provider, den ich sehe, verbunden. Sie sollten auch [SqlClient] (http://fsprojects.github.io/FSharp.Data.SqlClient/) erkunden. In Bezug auf Ihre Frage ist es ein bisschen schwierig ohne ein Beispiel für den Input/Output und Ihre Erwartung zu sagen. In der Tat ist der größte Teil der Funktionalität von Deedle auf ** Zeilen **. Wenn ich also mit Spalten arbeite, transponiere ich oft den Frame. Ist es möglich, dass Sie keine Indexspalte zugewiesen haben? Sagen Sie etwas wie: 'let df = df.IndexRows (" DateIndex ")'. – s952163

+0

In der Tat, was ich wissen muss, ist einfach: Deedle einen Index anhängen, um die Zeilen aufzuzählen, wenn ich versuche, auf Zeilen zuzugreifen, muss ich für diese Indez verweisen, aber ich weiß nicht, was ist. –

+0

Sie können den Index erhalten: 'df.RowIndex' und' df.RowIndex.Keys'. – s952163

Antwort

1

Mit Frame.ofRecords können Sie die Tabelle in einen Datenrahmen extrahieren und dann in ihren Zeilen oder Spalten arbeiten. In diesem Fall habe ich eine sehr einfache Tabelle. Dies ist für SQL Server, aber ich nehme an, MySQL wird das gleiche funktionieren. Wenn Sie in Ihrer Frage weitere Details angeben, kann die Lösung eingeschränkt werden.

Dies ist die Tabelle, die von ID indiziert, das ist Int64:

enter image description here

Sie können mit den Zeilen oder Spalten arbeiten:

#if INTERACTIVE 
#load @"..\..\FSLAB\packages\FsLab\FsLab.fsx" 
#r "System.Data.Linq.dll" 
#r "FSharp.Data.TypeProviders.dll" 
#endif 

//open FSharp.Data 
//open System.Data.Linq 
open Microsoft.FSharp.Data.TypeProviders 
open Deedle 

[<Literal>] 
let connectionString1 = @"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\userName\Documents\tes.sdf.mdf" 

type dbSchema = SqlDataConnection<connectionString1> 
let dbx = dbSchema.GetDataContext() 

let table1 = dbx.Table_1 


query { for row in table1 do 
     select row} |> Seq.takeWhile (fun x -> x.ID < 10L) |> Seq.toList 
// check if we can connect to the DB. 

let df = table1 |> Frame.ofRecords // pull the table into a df 
let df = df.IndexRows<System.Int64>("ID") // if you need an index 
df.GetRows(2L) // Get the second row, but this can be any kind of index/key 
df.["Number"].GetSlice(Some 2L, Some 5L) // get the 2nd to 5th row from the Number column 

erhalten Sie die folgende Ausgabe:

val it : Series<System.Int64,float> = 
2 -> 2 

> 
val it : Series<System.Int64,float> = 
2 -> 2 
3 -> 3 
4 -> 4 
5 -> 5 

Je nachdem, was Sie versuchen zu tun Selecting Specific Rows in Deedle könnte auch funktionieren.

bearbeiten

Von Ihrem Kommentar erscheinen Sie mit einigen großen Tisch zu arbeiten. Abhängig davon, wie viel Speicher Sie haben und wie groß die Tabelle ist, können Sie sie möglicherweise noch laden. Wenn diese nicht einig Dinge, die Sie in zunehmender Komplexität tun können:

  1. ein query { }expression wie oben Verwenden Sie den Datensatz auf dem Datenbankserver zu verengen und nur einen Teil des Ergebnisses in einen Datenrahmen umwandeln. Sie können ziemlich komplexe Transformationen durchführen, sodass Sie am Ende nicht einmal den Datenrahmen benötigen. Dies ist im Grunde Linq2Sql.

  2. Verwenden Sie lazy loading in Deedle. Dies funktioniert mit Serien, so dass Sie ein paar Serien erhalten und einen Datenrahmen wieder zusammensetzen können.

  3. Verwenden Sie Big Deedle, die für diese Art von Sache konzipiert ist.

+0

Ihre Antwort ist interessant, aber halten Sie mein Problem, wenn Sie sehen, dass Sie über Zeilen interessant sind, bevor Sie einen Datenrahmen erstellen, ist das Problem: Ich werde die ganze Tabelle lesen müssen, aber es ist groß. Die Art und Weise, wie ich die Tabellenreferenz in den Frame angehängt habe, so dass der Zugriff auf den Frame (die verschiedenen Filter usw.) während des Betriebs erfolgt, muss die Datenbank nicht gelesen und im Speicher gehalten werden. –

+0

Wissen Sie, wie kann ich diese direkte Referenz von einem Tisch wie deins machen? –

+0

@ AndréClaudino Sind Sie sicher, dass das ein Problem ist? Ich bin eigentlich nicht über die Zeilen iterieren, die 'Abfrage {...}' war nur ein Beispiel. Nein, Sie könnten Recht haben, und viele Daten in ein df zu werfen könnte problematisch sein. Ich werde mit einem großen Tisch testen. Aber in diesem Fall können Sie Linq2Sql (aka Abfrageausdrücke) oder vielleicht [Lazy Loading] (http://bluemountaincapital.github.io/Deedle/lazysource.html/) verwenden. Wir können diskutieren in [Chat] (http://chat.stackoverflow.com/rooms/51909/f) – s952163

Verwandte Themen