python—在计算列的和之后,自动在表中只插入一行

vpfxa7rd  于 2021-07-24  发布在  Java
关注(0)|答案(3)|浏览(265)

我的数据库中有3个表

CREATE TABLE IF NOT EXISTS  depances (
            id SERIAL PRIMARY KEY UNIQUE NOT NULL, 
            type VARCHAR NOT NULL,
            nom VARCHAR,
            montant DECIMAL(100,2) NOT NULL,
            date DATE,
            temp TIME)
CREATE TABLE IF NOT EXISTS transactions (
            id SERIAL PRIMARY KEY  UNIQUE NOT NULL,
            montant DECIMAL(100,2), 
            medecin VARCHAR,
            patient VARCHAR, 
            acte VARCHAR,
            date_d DATE, 
            time_d TIME,
            users_id INTEGER)
 CREATE TABLE IF NOT EXISTS  total_jr (
            id SERIAL PRIMARY KEY UNIQUE NOT NULL, 
            total_revenu DECIMAL(100,2),
            total_depance DECIMAL(100,2),
            total_différence DECIMAL(100,2),
            date DATE)

我的想法是使用gui接口在表depances和事务中插入defrent值。在这之后,将montant.depances之和加到total\u depance.total\u jr和montant.transactions之和加到total\u revenu.total\u jr,其中所有行的时间相同,这是使用此代码的简单部分

self.cur.execute( '''SELECT SUM(montant) AS totalsum FROM depances WHERE date = %s''',(date,))
        result = self.cur.fetchall()
        for i in result:
            o = i[0]

        self.cur_t = self.connection.cursor()

        self.cur_t.execute( '''INSERT INTO total_jr(total_depance) 
            VALUES (%s)'''
        , (o,))
        self.connection.commit()

        self.cur.execute( '''UPDATE total_jr SET total_depance = %s WHERE date = %s''',(o, date))
        self.connection.commit()

但每次它在total_jr的表中添加新行时
如何将sum的值(montant)添加到表中,在该表中,每次日期相同时,它只将sum的值放在一行中,而不是每次添加新行时,结果应该是这样的

id|total_revenu|total_depance|total_différence|date
--+------------+-------------+----------------+----
1  sum(montant1) value         value            08/07/2020
2  sum(montant2) value         value            08/09/2020
3  sum(montant3) value         value            08/10/2020

但它只给我这个结果

id|total_revenu|total_depance|total_différence|date
--+------------+-------------+----------------+----
1   1           value         value            08/07/2020
2   2           value         value            08/07/2020
3   3           value         value            08/7/2020

如果有任何想法或任何成功的话

eh57zj3b

eh57zj3b1#

你没有提到你正在使用哪个dbms或sql模块,所以我猜是mysql。
在您的过程中,首先运行更新并检查更改了多少行。如果更改了零行,则为该日期插入新行。

self.cur.execute( '''SELECT SUM(montant) AS totalsum FROM depances WHERE date = %s''',(date,))
result = self.cur.fetchall()
for i in result:
    o = i[0]

self.cur.execute( '''UPDATE total_jr SET total_depance = %s WHERE date = %s''',(o, date))

rowcnt = self.cur.rowcount  # number of rows updated - psycopg2
self.connection.commit()

if rowcnt == 0:  # no rows updated, need to insert new row
    self.cur_t = self.connection.cursor()

    self.cur_t.execute( '''INSERT INTO total_jr(total_depance, date) 
        VALUES (%s, %s)'''
    , (o, date))
    self.connection.commit()
bkkx9g8r

bkkx9g8r2#

我为将来需要它的人找到了一个解决方案首先我们需要更新表

create_table_total_jr = ''' CREATE TABLE IF NOT EXISTS  total_jr (
            id SERIAL PRIMARY KEY UNIQUE NOT NULL, 
            total_revenu DECIMAL(100,2),
            total_depance DECIMAL(100,2),
            total_différence DECIMAL(100,2),
            date DATE UNIQUE)''' #add unique to the date

在那之后,我们就开始使用upsert和on conflict

self.cur_t.execute( ''' INSERT INTO total_jr(date) VALUES (%s)
        ON CONFLICT (date) DO NOTHING''', (date,))
        self.connection.commit()

使用此代码,当有一个日期相同的插入值时,在更新和的值之后,它将不起任何作用

self.cur.execute( '''UPDATE total_jr SET total_depance = %s WHERE date = %s''',(o, date))
        self.connection.commit()

特别感谢mike67的帮助

dsf9zpds

dsf9zpds3#

您不需要为此调用2个数据库。正如@mike67所建议的,upsert功能就是你想要的。但是,您需要同时发送日期和总费用。在sql中变成:

insert into total_jr(date,total_depance) 
       values (date_value, total_value
        on conflict (date) 
        do update  
           set total_depance = excluded.total_depance;

或者取决于输入的total\u depance,仅为事务值,而在表中total\u depance是一个累加:

insert into total_jr(date,total_depance) 
       values (date_value, total_value
        on conflict (date) 
        do update  
           set total_depance = total_depance + excluded.total_depance;

我相信你的代码会变成这样(假设第一次插入是正确的)

self.cur_t.execute( ''' INSERT INTO total_jr(date,total_depance) VALUES (%s1,$s2)
        ON CONFLICT (date) DO UPDATE set total_depance = excluded.$s2''',(date,total_depance))
    self.connection.commit()

但这可能会关闭,你需要验证。
小贴士:您应该将列名date改为其他名称。date在postgres和sql标准中都是保留字。它根据上下文有预定义的含义。虽然你可以用它作为一个数据名,但postgres仍然有权随时更改,恕不另行通知,虽然不太可能,但仍然正确。如果是这样,那么您的代码(以及大多数使用该/这些表的代码)就会失败,并且跟踪原因变得非常困难。基本规则不使用保留字作为数据名;使用保留字作为数据或db对象名只是一个等待解决的bug。

相关问题