pandas Postgres中的基本实时更新

owfi6suc  于 2022-11-05  发布在  其他
关注(0)|答案(1)|浏览(163)

Postgres中的基本实时更新
大家好。我有一个Postgres数据库,我在其中创建了我的数据框架。因此,我的图形工作,我的计算工作,几乎一切都是美丽的。唯一的问题是,如果数据库发生变化,我需要停止Flask服务并重新启动,只有这样我的 Jmeter 板才能更新。
我展示了我的代码,这样别人就可以帮助解决它。当然,它不会为你工作,但也许你可以帮助我。
提前谢谢你,我说,它已经有一段时间了,我一直在试图解决它之前,张贴在这里。

我的布局和回调

'''

***Projeto dentro da pasta ProjetoDash***

pip install openpyxl
pip3 install psycopg2
pip3 install peewee
pip3 install dash
pip3 install pandas
pip install dash-bootstrap-components
pip install dash-bootstrap-templates
https://docs.microsoft.com/en-GB/cpp/windows/latest-supported-vc-redist?view=msvc-170

No PowerShell rode o comando:
Set-ExecutionPolicy Unrestricted

'''
import plotly.graph_objs as go
import dash
from dash import html, dcc, Input, Output, State, dash_table
import dash_bootstrap_components as dbc
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import pandas as pd

from dash_bootstrap_templates import ThemeSwitchAIO

# Importei meu dataframe do arquivo movimento_geral.py

from movimento_geral import *#df_dados_gerais  # , df_pivot
from graficos_geral import graficos
from tabela_geral import tabelas

# Formatação das tabelas

formatted = {'specifier': ',.2f', 'locale': {'group': '.', 'decimal': ',', }}

# Note que são muitos os dados, isso deve ser fitrado por ANO mas por enquanto limito o número de linhas com .head(15)

# este não é um gráfico adequado para mostrar nomes de produtos.

# print(df_dados_gerais_bar.head(15))

# import theme changer

from dash_bootstrap_templates import ThemeSwitchAIO

# ================================================================== #

from flask import Flask

dbc_css = "https://cdn.jsdelivr.net/gh/AnnMarieW/dash-bootstrap-templates/dbc.min.css"

server = Flask(__name__)

app = dash.Dash(__name__, server=server, suppress_callback_exceptions=True,
                external_stylesheets=[dbc.themes.BOOTSTRAP, dbc_css])

# ============================Styles================================ #

tab_card = {'height': '100%'}

main_config = {
    'hovermode': 'x unified',
    'legend': {
        'yanchor': 'top',
        'y': 0.9,
        'xanchor': 'left',
        'x': 0.1,
        'title': {'text': None},
        'font': {'color': 'white'},
        'bgcolor': 'rgba(0,0,0,0.0)'},
    'margin': {'l': 0, 'r': 0, 't': 20, 'b': 0}
}

df_dados_gerais = meus_dados()

# Aparência do sistema, cuidado com a ordem do Template_theme1 e 2

# em relação a url_teme

template_theme1 = 'cyborg'
template_theme2 = 'spacelab'
url_theme1 = dbc.themes.CYBORG
url_theme2 = dbc.themes.SPACELAB

# Separando Cidades + Global

s1_cidade_bairros = df_dados_gerais.groupby(['CIDADE', 'BAIRRO'])['TOTAL_OPERACAO'].sum().reset_index()
s2_todos = pd.DataFrame()
s2_todos['CIDADE'] = ['TODAS']
s2_todos['BAIRRO'] = ['TODOS']
s2_todos['TOTAL_OPERACAO'] = [0]
cidade_bairros = pd.concat([s1_cidade_bairros, s2_todos], ignore_index=True)

# To dict - Para salvar no dcc.store

df_store = df_dados_gerais.to_dict()

def layout():
    df_dados_gerais = meus_dados()
    dcc.Store(id='dataset', data=df_store),

    return dbc.Container([
    dcc.Store(id='dataset', data=df_store),

    dbc.Row([
        dbc.Col([
            dbc.Card([
                dbc.CardBody([
                    dbc.Row([
                        dbc.Col([
                            html.Legend("Bag Sales Metrics")
                        ], sm=9),
                        # dbc.Col([         
                        #    html.I(className='fa fa-gamepad', style={'font-size': '300%'})
                        # ], sm=3, align="left")
                    ]),
                    dbc.Row([
                        dbc.Col([
                            ThemeSwitchAIO(aio_id="theme", themes=[url_theme1, url_theme2]),
                            html.Legend("Rika Embalagens")
                        ])
                    ], style={'margin-top': '10px'}),
                    dbc.Row([
                        dbc.Button("Visite o Site", href="https://ajuda.alterdata.com.br/suporteexpress",
                                target="_blank")
                    ], style={'margin-top': '10px'})
                ])
            ], style=tab_card)
        ], sm=12, lg=3),

        dbc.Col([
            dbc.Row([
                dbc.Col([
                    dbc.Card([
                        dbc.CardBody([
                            dbc.Col([
                                # html.H5('Escolha o ano da sua pesquisa.', style={"font-weight": "bold"}),
                                dbc.Label("Escolha o ano da sua pesquisa."),
                                dcc.Slider(id='year-slider',
                                        min=int(df_dados_gerais['ANO'][1]),
                                        max=int(df_dados_gerais['ANO'].max()),
                                        marks={str(year): str(year) for year in
                                                sorted(df_dados_gerais['ANO'].unique())},
                                        value=int(df_dados_gerais['ANO'].max()),
                                        step=None,
                                        tooltip={'always_visible': False, 'placement': 'bottom'},
                                        className="mb-2"),
                            ], sm=12, style={'margin-top': '7px'}),
                        ])
                    ], style=tab_card)
                ])
            ]),

            dbc.Row([
                dbc.Col([
                    dbc.Card([
                        dbc.CardBody([
                            dbc.Col([
                                dbc.Label("Marque os mezes de sua pesquisa."),
                                dbc.Checklist(
                                    options=[
                                        {"label": "JAN", "value": 1},
                                        {"label": "FEV", "value": 2},
                                        {"label": "MAR", "value": 3},
                                        {"label": "ABR", "value": 4},
                                        {"label": "MAI", "value": 5},
                                        {"label": "JUN", "value": 6},
                                        {"label": "JUL", "value": 7},
                                        {"label": "AGO", "value": 8},
                                        {"label": "SET", "value": 9},
                                        {"label": "OUT", "value": 10},
                                        {"label": "NOV", "value": 11},
                                        {"label": "DEZ", "value": 12},
                                    ],
                                    #1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
                                    value=[11],
                                    id="check-inline-mes",
                                    inline=True,
                                    # switch=True,
                                ),
                            ], style={'margin-top': '7px'})
                        ])

                    ], style=tab_card)
                ], sm=12, lg=12),
            ], className='g-2 my-auto')
        ], sm=12, lg=9)

    ], className='g-2 my-auto', style={'margin-top': '7px'}),

    # Row 2
    dbc.Row([

        dbc.Col([
            dbc.Card([
                dbc.CardBody([
                    dbc.Row([
                        dbc.Col([
                            html.H5('Filtro por Cidade', style={"font-weight": "bold"}),
                            dcc.Dropdown(id='drop-cidade', multi=True, value=['TODAS', ],
                                        options=[{'label': name, 'value': name} for name in
                                                cidade_bairros['CIDADE'].unique()], className='dbc'),
                        ])
                    ])
                ])
            ], style=tab_card)
        ], sm=12, lg=6),

        dbc.Col([
            dbc.Card([
                dbc.CardBody([
                    dbc.Row([
                        dbc.Col([
                            html.H5('Filtro por Bairro', style={"font-weight": "bold"}),
                            dcc.Dropdown(id='drop-bairro', multi=True, value=['TODOS', ], className='dbc'),
                        ])
                    ])
                ])
            ], style=tab_card)
        ], sm=12, lg=6),

    ], className='g-2 my-auto', style={'margin-top': '7px'}),

    dbc.Row([
        dbc.Col([

            dbc.Tabs(
                [
                    dbc.Tab(
                        label="Gráficos", activeTabClassName="fw-bold fst-italic",
                        # active_tab_style={"textTransform": "uppercase"},
                        children=html.Div(graficos, className="p-4 border"),
                    ),
                    dbc.Tab(
                        label="Tabelas", activeTabClassName="fw-bold fst-italic",
                        # active_tab_style={"textTransform": "uppercase"},                        
                        # label="tab 2", active_label_style={"color": "#FB79B3"}
                        children=html.Div(tabelas, className="p-4 border"),
                    ),
                ], className="dbc",
            ),
        ], sm=12, lg=12)
    ], className='g-2 my-auto', style={'margin-top': '7px'})

], fluid=True, style={'height': '100vh'})

# Layout

# Layout

app.layout = layout

# * * * * * A FAZER * * * * *

# 1 - Adicionar filtro de canceladas.

# 2 - Adicionar check "Marca todas" nos meses.

# 3 - Adicionar Painel de valores:

# a) Vendas

# b) Devolução

# c) Compras

# a) Entradas

# ======== Callbacks ========== #

@app.callback(
    Output('drop-bairro', 'options'),
    Input('drop-cidade', 'value'))
def set_cities_options(selected_country):
    mask = cidade_bairros['CIDADE'].isin(selected_country)
    df_cidade_bairros = cidade_bairros.loc[mask]

    return [{'label': i, 'value': i} for i in df_cidade_bairros['BAIRRO'].unique()]

# Pie Charts

@app.callback(
    Output('graph0', 'figure'),
    Input('year-slider', 'value'),
    Input('drop-cidade', 'value'),
    Input('check-inline-mes', 'value'),
    Input(ThemeSwitchAIO.ids.switch("theme"), "value"),
    Input('drop-bairro', 'value')
)
def graph0(date, dropdown_cidade, mes, toggle, dropdown_bairro):
    template = template_theme1 if toggle else template_theme2

    if 'TODAS' in dropdown_cidade:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['MES'].isin(mes)) & (df_dados_gerais['CANCELADO'] != '*')
    else:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['CIDADE'].isin(dropdown_cidade)) & \
            (df_dados_gerais['BAIRRO'].isin(dropdown_bairro)) & (df_dados_gerais['MES'].isin(mes))  & (df_dados_gerais['CANCELADO'] != '*')

    df_subplot = df_dados_gerais.loc[mask]
    # Cria o mask de df_dados_gerais e faz os filtros
    # procura em df_dados_gerais as cidades do dropdown
    # cria novo objeto df_subplot recebendo o que aparecer de df_dados_gerais.loc[mask]    

    df_groups_v = df_subplot[df_subplot['OPERACAO'] == 'V'].groupby(['GRUPO'])[['TOTAL_OPERACAO']].sum()
    df_groups_v = df_groups_v.reset_index()
    df_groups_v.sort_values(by=['TOTAL_OPERACAO'], ascending=False, inplace=True)
    # df_subplot.to_excel('C:/Users/EliasPai/Desktop/df_groups.xlsx')

    df_groups_s = df_subplot[df_subplot['OPERACAO'] == 'S'].groupby(['GRUPO'])[['TOTAL_OPERACAO']].sum()
    df_groups_s = df_groups_s.reset_index()
    df_groups_s.sort_values(by=['TOTAL_OPERACAO'], ascending=False, inplace=True)

    df_groups_c = df_subplot[df_subplot['OPERACAO'] == 'C'].groupby(['GRUPO'])[['TOTAL_OPERACAO']].sum()
    df_groups_c = df_groups_c.reset_index()
    df_groups_c.sort_values(by=['TOTAL_OPERACAO'], ascending=False, inplace=True)

    df_groups_e = df_subplot[df_subplot['OPERACAO'] == 'E'].groupby(['GRUPO'])[['TOTAL_OPERACAO']].sum()
    df_groups_e = df_groups_e.reset_index()
    df_groups_e.sort_values(by=['TOTAL_OPERACAO'], ascending=False, inplace=True)

    subplot_topgames = make_subplots(rows=1, cols=4,
                                    specs=[[{"type": "pie"}, {"type": "pie"}, {"type": "pie"}, {"type": "pie"}]],
                                    subplot_titles=(
                                    "<b>Vendas</b>", "<b>Saídas</b>", "<b>Compras</b>", "<b>Entradas</b>"))

    values_v = df_groups_v['TOTAL_OPERACAO']
    subplot_topgames.add_trace(go.Pie(
        labels=df_groups_v['GRUPO'], values=values_v, hole=.2), row=1, col=1)

    subplot_topgames.add_trace(go.Pie(
        labels=df_groups_s['GRUPO'], values=df_groups_s['TOTAL_OPERACAO'], hole=.2), row=1, col=2)

    subplot_topgames.add_trace(go.Pie(
        labels=df_groups_c['GRUPO'], values=df_groups_c['TOTAL_OPERACAO'], hole=.2), row=1, col=3)

    subplot_topgames.add_trace(go.Pie(
        labels=df_groups_e['GRUPO'], values=df_groups_e['TOTAL_OPERACAO'], hole=.2), row=1, col=4)

    subplot_topgames.update_layout(margin={"l": 0, "r": 0, "t": 20, "b": 0}, height=200, template=template)

    return subplot_topgames

# --------------------------------------------------------------------------------------------

# Graph1 - Horizontal Bars

@app.callback(
    Output('graph1', 'figure'),
    Input('year-slider', 'value'),
    Input('drop-cidade', 'value'),
    Input('check-inline-mes', 'value'),
    Input(ThemeSwitchAIO.ids.switch("theme"), "value"),
    Input('drop-bairro', 'value')
)
def fig1(date, dropdown_cidade, mes, toggle, dropdown_bairro):
    template = template_theme1 if toggle else template_theme2
    if 'TODAS' in dropdown_cidade:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['OPERACAO'] == 'V') &  \
            (df_dados_gerais['MES'].isin(mes)) & (df_dados_gerais['CANCELADO'] != '*')
    else:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['OPERACAO'] == 'V') & \
            (df_dados_gerais['CIDADE'].isin(dropdown_cidade)) & (df_dados_gerais['BAIRRO'].isin(dropdown_bairro)) & \
            (df_dados_gerais['MES'].isin(mes)) & (df_dados_gerais['CANCELADO'] != '*')

    df_topglobal = df_dados_gerais.loc[mask]

    df_topglobal = df_topglobal.groupby(['VENDEDOR'])[['TOTAL_OPERACAO']].sum()
    df_topglobal = df_topglobal.reset_index()
    df_topglobal.sort_values(by=['TOTAL_OPERACAO'], ascending=False, inplace=True)
    #df_topglobal = df_topglobal.head(10).sort_values(by=['TOTAL_OPERACAO'])
    df_topglobal = df_topglobal.sort_values(by=['TOTAL_OPERACAO'])

    #    df_topglobal.to_excel('C:/Users/EliasPai/Desktop/2021.xlsx')

    text = [f'{x} - R${y:_.2f} '.replace('.', ',').replace('_', '.') for x, y in
            zip(df_topglobal['VENDEDOR'].unique(), df_topglobal['TOTAL_OPERACAO'].unique())]

    fig = go.Figure(go.Bar(x=df_topglobal['TOTAL_OPERACAO'], y=df_topglobal['VENDEDOR'], orientation='h', text=text))
    fig.update_layout(main_config, height=310, xaxis={'title': None, 'showticklabels': False},
                    yaxis={'title': None, 'showticklabels': False}, template=template)
    return fig

# Graph 2 - Line Chart

@app.callback(
    Output('graph2', 'figure'),
    Input('year-slider', 'value'),
    Input('drop-cidade', 'value'),
    Input('check-inline-mes', 'value'),
    Input(ThemeSwitchAIO.ids.switch("theme"), "value"),
    Input('drop-bairro', 'value')
)
def long(date, dropdown_cidade, mes, toggle, dropdown_bairro):
    template = template_theme1 if toggle else template_theme2
    if 'TODAS' in dropdown_cidade:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['OPERACAO'] == 'V') &  \
            (df_dados_gerais['MES'].isin(mes)) & (df_dados_gerais['CANCELADO'] != '*')
    else:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['OPERACAO'] == 'V') & \
            (df_dados_gerais['CIDADE'].isin(dropdown_cidade)) & (df_dados_gerais['BAIRRO'].isin(dropdown_bairro)) & \
            (df_dados_gerais['MES'].isin(mes)) & (df_dados_gerais['CANCELADO'] != '*')

    df_anos = df_dados_gerais.loc[mask]

    trace = df_anos.groupby('MES')['TOTAL_OPERACAO'].sum().reset_index()

    trace['MES'] = trace['MES'].map({1: 'JAN',
                                    2: 'FEV',
                                    3: 'MAR',
                                    4: 'ABR',
                                    5: 'MAI',
                                    6: 'JUN',
                                    7: 'JUL',
                                    8: 'AGO',
                                    9: 'SET',
                                    10: 'OUT',
                                    11: 'NOV',
                                    12: 'DEZ'},
                                    na_action=None)

    fig_anos = go.Figure(go.Scatter(x=trace['MES'], y=trace['TOTAL_OPERACAO'], mode='lines+markers', fill='tonexty',
                                    name='Global Sales'))

    fig_anos.update_layout(main_config, height=200, xaxis={'title': 'None'}, yaxis={'title': None}, template=template)

    fig_anos.add_annotation(text=f'Vendas em Reais de {date}',
                            xref="paper", yref="paper",
                            font=dict(
                                size=20,
                                color='white'
                            ),
                            align="center", bgcolor="rgba(0,0,0,0.8)", opacity=0.8,
                            x=0.5, y=0.5, showarrow=False)

    return fig_anos

# Indicator 1 and 2

@app.callback(
    Output('card_venda', 'children'),
    Output('card_desconto', 'children'),
    Output('card_devolucao', 'children'),
    Output('card_venda_liquida', 'children'),
    Input('year-slider', 'value'),
    Input('drop-cidade', 'value'),
    Input('check-inline-mes', 'value'),
    Input(ThemeSwitchAIO.ids.switch("theme"), "value"),
    Input('drop-bairro', 'value')
)
def ind1(date, dropdown_cidade, mes, toggle, dropdown_bairro):
    template = template_theme1 if toggle else template_theme2

    #if 'TODAS' in dropdown_cidade:
    #    mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['OPERACAO'] == 'V') &  \
    #           (df_dados_gerais['MES'].isin(mes)) & (df_dados_gerais['CANCELADO'] != '*')
    #else:
    #    mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['OPERACAO'] == 'V') & \
    #           (df_dados_gerais['CIDADE'].isin(dropdown_cidade)) & (df_dados_gerais['BAIRRO'].isin(dropdown_bairro)) & \
    #           (df_dados_gerais['MES'].isin(mes)) & (df_dados_gerais['CANCELADO'] != '*')

    if 'TODAS' in dropdown_cidade:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['MES'].isin(mes))
    else:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['CIDADE'].isin(dropdown_cidade)) & \
            (df_dados_gerais['BAIRRO'].isin(dropdown_bairro)) & (df_dados_gerais['MES'].isin(mes))

    df_vendas = df_dados_gerais[(df_dados_gerais['OPERACAO'] == 'V') & (df_dados_gerais['CANCELADO'] != '*')].loc[mask]    
    venda_bruta = df_vendas['TOTAL_OPERACAO'].sum()

    df_desconto = df_dados_gerais[(df_dados_gerais['OPERACAO'] == 'V') & (df_dados_gerais['CANCELADO'] != '*')].loc[mask].drop_duplicates(subset='NUMERO')
    df_desconto = df_desconto['DESCONTO_GLOBAL'].sum() 
    desconto = df_desconto

    troca_devolucao = ['T', 'D']
    df_devolucao = df_dados_gerais[(df_dados_gerais['OPERACAO'] == 'E') & \
                                (df_dados_gerais['DEVOLUCAO'].isin(troca_devolucao))].loc[mask]

    #df_devolucao.to_excel('C:/Users/EliasPai/Desktop/df_devolucao.xlsx') 
    devolucao = df_devolucao['TOTAL_OPERACAO'].sum() - df_devolucao['DESCONTO_GLOBAL'].sum()

    venda_liquida = venda_bruta - df_desconto

    return f'Vendas: R${venda_bruta:_.2f} '.replace('.', ',').replace('_', '.'), \
        f'Descontos: R${desconto:_.2f} '.replace('.', ',').replace('_', '.'), \
        f'Devoluções: R${devolucao:_.2f} '.replace('.', ',').replace('_', '.'), \
        f'Total: R${venda_liquida:_.2f} '.replace('.', ',').replace('_', '.')

# Na aba TABELAS, conteúdo da tabela.

@app.callback(
    Output('datatable-data', 'data'),
    Output('datatable-data', 'columns'),
    Input('year-slider', 'value'),
    Input('drop-cidade', 'value'),
    Input('check-inline-mes', 'value'),
    Input(ThemeSwitchAIO.ids.switch("theme"), "value"),
    Input('drop-bairro', 'value'))
def update_table(date, dropdown_cidade, mes, toggle, dropdown_bairro):
    template = template_theme1 if toggle else template_theme2

    if ('TODAS' in dropdown_cidade):
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['OPERACAO'] == 'V') &  \
            (df_dados_gerais['MES'].isin(mes)) & (df_dados_gerais['CANCELADO'] != '*')
    else:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['OPERACAO'] == 'V') & \
            (df_dados_gerais['CIDADE'].isin(dropdown_cidade)) & (df_dados_gerais['BAIRRO'].isin(dropdown_bairro)) & \
            (df_dados_gerais['MES'].isin(mes)) & (df_dados_gerais['CANCELADO'] != '*')

    df = df_dados_gerais.loc[mask]

    #'QT_PRATELEIRA', 'QT_DEPOSITO', 
    df_pivot = pd.pivot_table(
        df_dados_gerais.loc[mask], index=['CODIGO', 'DESCRICAO',
                'ESTOQUE', 'GRUPO',
                'FAMILIA', 'UNIDADE',],
        values='QUANTIDADE',
        columns='MES',
        aggfunc=sum).reset_index().fillna(0)

    df_pivot = df_pivot.rename(
        {1: 'JAN', 2: 'FEV', 3: 'MAR', 4: 'ABR', 5: 'MAI', 6: 'JUN', 
        7: 'JUL', 8: 'AGO', 9: 'SET', 10: 'OUT', 11: 'NOV', 12: 'DEZ'}, axis=1)

    cols = []

    textCols = ['CODIGO', 'DESCRICAO', 'GRUPO', 'FAMILIA', 'UNIDADE']

    for i in df_pivot.columns:
        if i not in textCols:
            cols.append({"name": str(i),
                    "id": str(i),
                    "type": "numeric",
                    "format": formatted})
        else:
            cols.append({"name": str(i),
                        "id": str(i),
                        "type": "text"})

    return df_pivot.to_dict('records'), cols

if __name__ == '__main__':
    app.run_server(debug=False)
lstz6jyr

lstz6jyr1#

我用mysql做了一些类似下面的事情。请参考它,并检查它是否符合您的要求。

dcc.Store(id='store-data', data=[], storage_type='memory'), # 'local' or 'session'    
    dcc.Interval(id='update', n_intervals = 0, interval=1000*30)
])

@app.callback(Output('store-data','data'),
             [Input('update', 'n_intervals')])

def update_data(n):
    global jobs_2
    db = mysql.connector.connect(
        host="localhost",              
        user="root",            
        password="",        
        database="indeed_data_dump")   

    cur = db.cursor()
    cur.execute("SELECT * FROM jobs")
    columns = [col[0] for col in mycursor.description]
    data = mycursor.fetchall()
    jobs_2 = pd.DataFrame(data, columns=columns)
    db.close()
    jobs_2.to_dict()

相关问题