AttributeError: Can only use .dt accessor with datetimelike values

Hello,
I’m getting this error when trying to get the a download link for an excel file.The application works and gives the output and the diagrams.
Do you guys know what exactly gives this error?
Below I will paste my code,if you need any more information I can do it.

Traceback (most recent call last):
  File "C:\Users\denis.akvic\Desktop\BDE\flask\apps\app1.py", line 733, in download_sheet
    df["Timestamp"] = df["Timestamp"].dt.tz_localize(None)
  File "C:\Users\denis.akvic\AppData\Local\Programs\Python\Python39\Lib\site-packages\pandas\core\generic.py", line 5487, in __getattr__
    return object.__getattribute__(self, name)
  File "C:\Users\denis.akvic\AppData\Local\Programs\Python\Python39\Lib\site-packages\pandas\core\accessor.py", line 181, in __get__
    accessor_obj = self._accessor(obj)
  File "C:\Users\denis.akvic\AppData\Local\Programs\Python\Python39\Lib\site-packages\pandas\core\indexes\accessors.py", line 506, in __new__
    raise AttributeError("Can only use .dt accessor with datetimelike values")
AttributeError: Can only use .dt accessor with datetimelike values

This is the link12 code

@app.callback(Output("link12", "children"),
             [Input("excel_data_error_log", "data")],
            state=[State("start_date_picker", "date"),
            State("start_time_picker", "value"),
            State("end_date_picker", "date"),
            State("end_time_picker", "value"),
            State("database", "value")])
def download_sheet(output, start_date_picker, start_time_picker, end_date_picker, end_time_picker, database):
    if not output:
        return None
    df = pd.read_json(output, orient='split')
    df["Timestamp"] = df["Timestamp"].dt.tz_localize(None)
    start_time = datetime.datetime.strptime(start_date_picker, "%Y-%m-%d") + datetime.timedelta(hours=int(start_time_picker[0:2]))
    end_time = datetime.datetime.strptime(end_date_picker, "%Y-%m-%d") + datetime.timedelta(hours=int(end_time_picker[0:2]))
    xlsx_io = io.BytesIO()
    writer = pd.ExcelWriter(xlsx_io, engine='xlsxwriter', options={"remove_timezone" : True})
    df.to_excel(writer, sheet_name="Error Log")
    writer.save()
    xlsx_io.seek(0)
    # https://en.wikipedia.org/wiki/Data_URI_scheme
    media_type = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    data = base64.b64encode(xlsx_io.read()).decode("utf-8")
    href_data_downloadable = f'data:{media_type};base64,{data}'
    file_name = "Error_Log-{0}-{1}_{2}.xlsx".format(str(database), start_time, end_time)
    return html.A("Error Log Raw Data", download=file_name, href=href_data_downloadable)

I updated my database and this happened.
This is my code for the sql query

def query_db_parts(n_clicks, db_name, language, start_date_picker, start_time_picker, end_date_picker, end_time_picker, part_type, worker_name):
    if n_clicks:
        start_time = datetime.datetime.strptime(start_date_picker, "%Y-%m-%d") + datetime.timedelta(hours=int(start_time_picker[0:2]))
        end_time = datetime.datetime.strptime(end_date_picker, "%Y-%m-%d") + datetime.timedelta(hours=int(end_time_picker[0:2]))
        error_code = input_check_time(start_time, end_time)

        #start_time = start_date_picker + " " + start_time_picker[0:2] + ":00"
        #end_time = end_date_picker + " " + end_time_picker[0:2] + ":00"

        if error_code:
            df = pd.DataFrame(data=None)
            df = df.to_json(date_format='iso', orient='split')
            return None, None, None


        parameters = [start_time, end_time]
        print(parameters)

        query_string = mssql_queries.build_db_query_string_app2()
        records = mssql_conn.execute_query(query_string, parameters, db_name)

        #query_string = mysql_queries.build_db_query_string_app2(db_name)
        #records = connect.execute_query(query_string, parameters, db_name)

        if not records:
            return None, None, None

        query_output = pd.DataFrame.from_records(records)
        query_output.columns = ["ID", "Timestamp", "Type", "Result"]

        if part_type != "all" or worker_name != "all":
            
            if part_type != "all":
                part_type_filter = utils.create_part_type_filter(db_name, parameters, part_type)
                print(part_type_filter)

                if part_type_filter.empty:
                    return None, None, None
                
                query_output = utils.apply_filter(query_output, part_type_filter)
            
            if worker_name != "all":
                worker_filter = utils.create_worker_filter(db_name, parameters, worker_name)

                if worker_filter.empty:
                    return None, None, None

                query_output = utils.apply_filter(query_output, worker_filter)

            if query_output.empty:
                    return None , None, None
        categories = query_output.groupby("Result").count()
        if categories["ID"][0] == False:
            faulty_parts = categories["ID"][0]
            ok_parts = categories["ID"][1]
        else:
            faulty_parts = 0
            ok_parts = categories["ID"][0]   
        query_output["time_diff"] = 0
        for i in range(query_output.shape[0] - 1):
            query_output["time_diff"][i+1] = (query_output['Timestamp'][i+1] - query_output['Timestamp'][i]).total_seconds()
        mean_cycle_time = round(query_output["time_diff"].mean(), 2)
        return "OK Parts: {}".format(ok_parts) , "Faulty Parts: {}".format(faulty_parts), "Mean Cycle Time: {}".format(mean_cycle_time)
    return None, None, None

And the sql query itself:

def build_db_query_string_app1(language):
    db_query_string = """SELECT NotificationLog.FailureCode, FailureDescription.[Alarm text  de-DE , Alarm text]text, NotificationLog.Duration, NotificationLog.Timestamp
                            FROM NotificationLog, FailureDescription
                            WHERE NotificationLog.Timestamp
                                BETWEEN ? AND ?
                                AND FailureDescription.ID = NotificationLog.FailureCode;""".format(language)
    return db_query_string

so you think that making .dt into hours_series.dt.hour will make it work for me?
I always used .dt for my other apps and it worked fine before

I did it and I get this error.

TypeError: index is not a valid DatetimeIndex or PeriodIndex

raceback (most recent call last):
  File "C:\Users\denis.akvic\Desktop\BDE\flask\apps\app1.py", line 733, in download_sheet
    df["Timestamp"] = df["Timestamp"].tz_localize(None)
  File "C:\Users\denis.akvic\AppData\Local\Programs\Python\Python39\Lib\site-packages\pandas\core\generic.py", line 9694, in tz_localize
    ax = _tz_localize(ax, tz, ambiguous, nonexistent)
  File "C:\Users\denis.akvic\AppData\Local\Programs\Python\Python39\Lib\site-packages\pandas\core\generic.py", line 9676, in _tz_localize
    raise TypeError(
TypeError: index is not a valid DatetimeIndex or PeriodIndex

Is that a column of strings?
You may need to convert it with pd.to_datetime first.
Sorry, I wasted some time in the misunderstanding.

Can you show me an example so I understand it better?

I added

df["Timestamp"] = pd.to_datetime(df["Timestamp"],format= "%d-%b-%Y %H:%M:%S")

and now I get

ValueError: time data '144' does not match format '%d-%b-%Y %H:%M:%S' (match)


File "C:\Users\denis.akvic\AppData\Local\Programs\Python\Python39\Lib\site-packages\pandas\core\tools\datetimes.py", line 509, in _to_datetime_with_format

values, tz = conversion.datetime_to_datetime64(arg)

File "pandas\_libs\tslibs\conversion.pyx", line 359, in pandas._libs.tslibs.conversion.datetime_to_datetime64

It looks like an outlier, just pick it out and deal with it.

I added
df["Timestamp"] = pd.to_datetime(df["Timestamp"],format= "%Y-%m-%d %H:%M:%S")

Now I can download [Error Log Raw Data] but when I do it get

The timestamp is weird and it’s giving not the correct one.

Aha, the problem should be in a certain step of pandas operation, try several more times.

I tried it again,but it gives this weird timestamp.Do you have any idea what exactly should i look for? Thank you.

Hey, can you do a print(df.head()) and show us the output right after this line? before doing a pd.to_datetime on the column. This would help give a clearer idea about the data that’s in your dataframe

Like he said, do more print operation, especially before and after you manipulate that column of time series, to make sure you get what you want. You can print columns, headers, or a key cell.

This is what I’m getting

[datetime.datetime(2021, 12, 1, 6, 0), datetime.datetime(2021, 12, 2, 6, 0)]
SELECT NotificationLog.FailureCode, FailureDescription.[Alarm text  de-DE , Alarm text]text, NotificationLog.Duration, NotificationLog.Timestamp
                            FROM NotificationLog, FailureDescription
                            WHERE NotificationLog.Timestamp
                                BETWEEN ? AND ?
                                AND FailureDescription.ID = NotificationLog.FailureCode;
SELECT FailureDescription.ID,
                            FailureDescription.[Alarm text  de-DE , Alarm text],
                            --NotificationLog.FailureCode,
                            NotificationLog.Timestamp,
                                                        NotificationLog.Duration
                            FROM NotificationLog, FailureDescription
                            WHERE NotificationLog.Timestamp
                            BETWEEN ? AND ?
                            AND FailureDescription.ID = NotificationLog.FailureCode;
SELECT ItemLog.ID, ItemLog.Timestamp, ItemLog.Type, ItemLog.Result 
                         FROM ItemLog
                         WHERE ItemLog.Timestamp BETWEEN ? AND ?
c:\Users\denis.akvic\Desktop\BDE\flask\apps\app1.py:337: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  query_output["time_diff"][i+1] = (query_output['Timestamp'][i+1] - query_output['Timestamp'][i]).total_seconds()
2021-12-01_06-00-00
2021-12-02_06-00-00
c:\Users\denis.akvic\Desktop\BDE\flask\apps\app1.py:337: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  query_output["time_diff"][i+1] = (query_output['Timestamp'][i+1] - query_output['Timestamp'][i]).total_seconds()
    Error ID                                         Alert Text  Error Count Down Time  Relative Down Time  Estimated Loss  Cumulative Percentage
0          3                             RT3: Not-Halt Betätigt            5  02:56:37               24.83             283                  24.83
56     20015           Station 20 Prüfachse meldet einen Fehler            6  02:01:19               17.06             194                  41.89
33      8002  Station 8 Vertikal 1 Vorlauf -95B371.3 verstel...            3  01:58:45               16.70             190                  58.59
59     21053    Station 21 Sensor Max Stau nicht frei -81B257.3          173  01:06:18                9.32             106                  67.91
39     10008  Station 10 Loch Ausrichten Vorlauf -94B370.7 v...           62  00:34:11                4.81              55                  72.72
..       ...                                                ...          ...       ...                 ...             ...                    ...
8       3009  Station 3 Einsetzen Vertikal 1 Ruhelage -80B15...            2  00:00:13                0.03               0                  99.94
13      5013  Station 5 Links Abteilen Horizontal Ruhelage -...            1  00:00:11                0.03               0                  99.97
50     16006  Station 16 Horizontal Prüfen Vorlauf -75B251.5...            1  00:00:11                0.03               0                 100.00
28      7005  Station 7 Abteilen Neigen Ruhelage -88B364.2 v...            1  00:00:06                0.01               0                 100.00
24      6002  Station 6 Aufnahme öffnen Vorlauf -86B362.5 ve...            1  00:00:06                0.01               0                 100.00

[64 rows x 7 columns]c:\Users\denis.akvic\Desktop\BDE\flask\apps\app1.py:337: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  query_output["time_diff"][i+1] = (query_output['Timestamp'][i+1] - query_output['Timestamp'][i]).total_seconds()

   Failure Code                                Failure Description                  Duration  Timestamp
0         12051  Station 12 Sensor Stange in Taktband nicht bel...  2021-12-01T09:23:01.983Z        144
1         12051  Station 12 Sensor Stange in Taktband nicht bel...  2021-12-01T10:30:36.527Z         69
2         12051  Station 12 Sensor Stange in Taktband nicht bel...  2021-12-01T10:43:06.570Z         60
3         15004  Station 15 Fixierung Zustellen Vorlauf -81B257...  2021-12-01T10:43:06.970Z         72
4         16005  Station 16 Horizontal Prüfen Ruhelage -75B251....  2021-12-01T14:30:55.973Z        339c:\Users\denis.akvic\Desktop\BDE\flask\apps\app1.py:337: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  query_output["time_diff"][i+1] = (query_output['Timestamp'][i+1] - query_output['Timestamp'][i]).total_seconds()

c:\Users\denis.akvic\Desktop\BDE\flask\apps\app1.py:738: FutureWarning: Use of **kwargs is deprecated, use engine_kwargs instead.
  writer = pd.ExcelWriter(xlsx_io, engine='xlsxwriter', options={"remove_timezone" : True})
c:\Users\denis.akvic\Desktop\BDE\flask\apps\app1.py:337: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  query_output["time_diff"][i+1] = (query_output['Timestamp'][i+1] - query_output['Timestamp'][i]).total_seconds()
C:\Users\denis.akvic\AppData\Local\Programs\Python\Python39\lib\site-packages\plotly\graph_objs\_deprecations.py:322: DeprecationWarning: plotly.graph_objs.Font is deprecated.
Please replace it with one of the following more specific types
  - plotly.graph_objs.layout.Font
  - plotly.graph_objs.layout.hoverlabel.Font
  - etc.

  warnings.warn(
c:\Users\denis.akvic\Desktop\BDE\flask\apps\app1.py:337: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  query_output["time_diff"][i+1] = (query_output['Timestamp'][i+1] - query_output['Timestamp'][i]).total_seconds()
c:\Users\denis.akvic\Desktop\BDE\flask\apps\app1.py:337: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  query_output["time_diff"][i+1] = (query_output['Timestamp'][i+1] - query_output['Timestamp'][i]).total_seconds()
c:\Users\denis.akvic\Desktop\BDE\flask\apps\app1.py:337: SettingWithCopyWarning:


A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy

c:\Users\denis.akvic\Desktop\BDE\flask\apps\app1.py:677: FutureWarning:

Use of **kwargs is deprecated, use engine_kwargs instead.

I think you messed up with the timestamp and duration columns, it looks like your duration is your actual timestamp and vice versa. Switch out the column names argument in your sql request code.

Also when you do your df[“Timestamp”] = pd.to_datetime(df[“Timestamp”],format= “%Y-%m-%d %H:%M:%S”) , omit the format argument because yours is wrong and will currently throw an error.

1 Like

Okay I will,but do you meand in the python code like:

query_output.columns = ["Error ID", "Alert Text", "Duration", "Timestamp"]

or my database query in the microsoft SQL management studio ?

python code i.e. your Timestamp is your duration and inverse. Just took a look at your query code, maybe it’s just simpler to rename the columns when you get your data in your callback here:

df[['Duration','Timestamp']]=df['Timestamp','Duration']]

might be the simplest solution to your problem. you’d have to add it right after df creation

    df = pd.read_json(output, orient='split')
    df[['Duration','Timestamp']]=df[['Timestamp','Duration']]