Skip to content

No timestamp returned via POCO based QueryAsync<T> #119

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
ritchiecarroll opened this issue Aug 31, 2020 · 9 comments · Fixed by #121
Closed

No timestamp returned via POCO based QueryAsync<T> #119

ritchiecarroll opened this issue Aug 31, 2020 · 9 comments · Fixed by #121
Assignees
Milestone

Comments

@ritchiecarroll
Copy link
Contributor

ritchiecarroll commented Aug 31, 2020

With a simple class like the following:

    [Measurement("point")]
    public class Point
    {
        [Column("tag", IsTag = true)] public string Tag { get; set; }
        [Column("min")] public double Minimum { get; set; }
        [Column("max")] public double Maximum { get; set; }
        [Column("avg")] public double Average { get; set; }
        [Column("flags")] public uint QualityFlags { get; set; }
        [Column(IsTimestamp = true)] public DateTime Timestamp { get; set; }
    }

Data writes fine and I can verify through a CLI query that timestamps are accurately stored, but when retriving data, the timestamp is always zero, i.e., DateTime.MinValue.

Here's the query code:

        public static async IAsyncEnumerable<Point> ReadPoints(string influxDBHost, string fluxQuery)
        {
            using InfluxDBClient influxDBClient = InfluxDBClientFactory.Create(influxDBHost, Token);
            QueryApi queryAPI = influxDBClient.GetQueryApi();

            List<Point> points = await queryAPI.QueryAsync<Point>($"from(bucket:\"{PointBucket}\"){fluxQuery}", OrganizationID);

            foreach (Point point in points)
                yield return point;
        }

Seems like the marked IsTimestamp column is being missed during deserialization.

Also, tried several variations on POCO timestamp column:

[Column("Timestamp", IsTimestamp = true)] public DateTime Timestamp;
[Column("time", IsTimestamp = true)] public DateTime Timestamp;
[Column("_time", IsTimestamp = true)] public DateTime Timestamp;
[Column(IsTimestamp = true)] public DateTime Time;
@rhajek rhajek assigned rolincova and rhajek and unassigned rolincova Sep 1, 2020
@ritchiecarroll
Copy link
Contributor Author

As a side note, have you considered creating an overload that will directly return an IAsyncEnumerable<T> from a QueryAsync method as an optimization?

Could even provide a new method like QueryAsyncEnumerable<T>

@ritchiecarroll
Copy link
Contributor Author

As a side note, have you considered creating an overload that will directly return an IAsyncEnumerable<T> from a QueryAsync method as an optimization?

Could even provide a new method like QueryAsyncEnumerable<T>

I added a pull request for this feature #121

FYI, this PR includes both the timestamp fix plus the enhancement - let me know if I should separate these.

@rhajek
Copy link
Contributor

rhajek commented Sep 4, 2020

Hi @ritchiecarroll, thanks for using our client library and creating PRs. We will include them in the next release. I tried couple of tests and deserialisation of timestamp works only with Column.Name annotation set on "time".

[Column("time", IsTimestamp = true)] public DateTime Timestamp { get; set; }

I found also problem with DateTime.Now, Poco with such timestamp is not written to InfluxDB, System.ArgumentException : Timestamps must be specified as UTC is not propagated or shown.

We definitely need to add more unit tests related to Poco and timestamps.

@rhajek rhajek added this to the 1.12.0 milestone Sep 4, 2020
@bednar bednar removed this from the 1.12.0 milestone Sep 9, 2020
@bednar bednar added this to the 1.13.0 milestone Oct 2, 2020
@shialex
Copy link

shialex commented Mar 11, 2021

I am experiencing a similar issue where querying DateTime via a POCO always returns DateTime.MinValue using InfluxDB.Client 1.15.0. It doesn't just happen with DateTime either, I'm using logic similar to the one found here https://github.com/influxdata/influxdb-client-csharp/tree/master/Client#queries.

var cycles = await queryApi.QueryAsync<Cycle>(flux, "org_id");

Our object looks like the following:

[Measurement("cycle")]
public class Cycle
{
    [Column(IsTimestamp = true)] public DateTime Time;
    [Column("cycle_start")] public DateTime CycleStart { get; set; }
    [Column("cycle_end")] public DateTime CycleEnd { get; set; }
    [Column("count")] public int Count { get; set; }
    [Column("name")] public string Name { get; set; }
    ...
}

Looking through the queried cycles list, all CycleStart and CycleEnd will have DateTime.MinValue as their value even though I can verify that the values being published correctly. The same goes for Count and Name, they do not seem to get queried correctly and are defaulted to 0 and null respectively.

@bednar
Copy link
Contributor

bednar commented Mar 12, 2021

Hi @shialex,

Could you share how you Flux query looks like? The query should use pivot() function, something like:

var query = $"from(bucket:\"{bucket}\") " +
                        "|> range(start: 0) " +
                        "|> pivot(rowKey:[\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\")";

Check out this example: PocoQueryWriteExample.cs.

Regards

@shialex
Copy link

shialex commented Mar 12, 2021

Hello @bednar,

You are completely correct, I forgot about the pivot() function in the Flux query.

I'm using the query you posted and everything queried seems correct now but Time is still DateTime.MinValue.

@teddybee
Copy link

teddybee commented Mar 20, 2021

@bednar I have the same issue as @shialex , the timestamp in the POCO is 0001. 01. 01. 0:00:00. I used the pivot in flux.
The root cause probably in the fluxRecord.GetTimeInDateTime() method, as it also has this fault.
fluxRecord.GetTime() is working well.

@wen2204
Copy link

wen2204 commented Sep 1, 2021

Hi ,I encounter the same error with the lateast version InfluxDB.Client 2.1.0.
//this is the class.

[Measurement("temperature")]
        private class Temperature
        {
            [Column("location", IsTag = true)] 
            public string Location { get; set; }

            [Column("value")] 
            public double Value { get; set; }

            [Column("time", IsTimestamp = true)] 
            public DateTime Time;
        }

      //this is query code:
        var flux2 = $"from(bucket:\"{bucket}\") |> range(start: 0) " +
                        "|> pivot(rowKey:[\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\")";
            var temperatures = await influxDBClient.GetQueryApi().QueryAsync<Temperature>(flux2, org);
            temperatures.ForEach(temperature =>
            {
                _logger.LogInformation($"{temperature.Location}: {temperature.Value} at {temperature.Time}");
            });

the temperature.Time is still the wrong time:0001/1/1 0:00:00

@bednar
Copy link
Contributor

bednar commented Sep 6, 2021

Hi @wen2204,

Can you share debug output from client? You can enable debug mode by:

var client = InfluxDBClientFactory.Create("http://localhost:9999",
    "my-token".ToCharArray());
client.SetLogLevel(LogLevel.Body);

Regards

# for free to join this conversation on GitHub. Already have an account? # to comment