当前位置: 代码迷 >> python >> 根据python中的多个条件从访问表中删除行以及日期字段
  详细解决方案

根据python中的多个条件从访问表中删除行以及日期字段

热度:94   发布时间:2023-07-14 08:44:06.0

我试图基于两列之一(即released_by和released_date)从访问数据库表中删除行。

Sudo code

WHERE released_by  = '27' and released_date would change based on the day of the month. 

如果day == 1,则为Released_Date,然后删除上个月的数据,否则删除当前的月份数据。

import pandas as pd
import numpy as np
import datetime
from datetime import date
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
import pyodbc
import calendar
import xlrd
import defusedxml
from defusedxml.common import EntitiesForbidden
from xlrd import open_workbook
defusedxml.defuse_stdlib()

# connecting to access database
conn = pyodbc.connect(r'Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=C:\Users\Desktop\Insights.accdb;')
insights_dbcurs = conn.cursor()

select_auto_releases = "SELECT * FROM RELEASES WHERE RELEASED_BY = '27'"
autoreleases = insights_dbcurs.execute(select_auto_releases).fetchall()
#display(autoreleases)

for row in autoreleases:
    previousmonth = datetime.now() - relativedelta(months=1)
    previousmonth = previousmonth.strftime("%m - %Y")
    currentmonth = datetime.now()
    currentmonth = currentmonth.strftime("%m - %Y")
    if ((row.autoreleases['RELEASED_DATE']).strftime) ==1:
        try:
            delete = 'DELETE * FROM RELEASES WHERE RELEASED_DATE = ? and RELEASED_BY = ?'
            insights_dbcurs.execute(delete,{'RELEASED_DATE':currentmonth},{'RELEASED_BY':'27'})
        except:
            delete = 'DELETE * FROM RELEASES WHERE RELEASED_DATE = ? and RELEASED_BY = ?'
            insights_dbcurs.execute(delete,{'RELEASED_DATE':previousmonth},{'RELEASED_BY':'27'})

insights_dbcurs.close()
conn.commit()
conn.close()

这是行不通的。 我得到:

AttributeError:'pyodbc.Row'对象没有属性'autoreleases'

如果我删除Row.autorelease ,我得到

sql具有0个属性,其中2个正在传递。

我如何避免这种情况。 任何建议都会很有帮助。

考虑将代码重构为几个问题:

  1. try/except通常用于处理运行时异常和错误,而不是应用程序逻辑。 在这些情况下使用if/else

  2. 删除不需要的for循环,因为您不会逐行删除,因为没有唯一的标识符传递到DELETE语句中。 实际上,如果逻辑将未过滤的当前行传递到该行,则您正在整个表上运行删除过程。

  3. 将纯SQL与一个DELETE语句一起使用,并避免对时间元素进行Python处理,因为这会维护数据库中的转换问题。 MS Access SQL具有用于月/日提取的日期函数,例如Date() (当前日期)和DatePart() 此外,MS Access 可以DELETE运行复杂的子查询逻辑。

的SQL

对两个日期条件都使用IN子查询。 注意: ID应该替换为表的唯一标识符。 DELETE版本之前检查查询的SELECT版本。

DELETE FROM RELEASES r
WHERE r.ID IN
  (SELECT sub.ID  
   FROM RELEASES sub
   WHERE sub.RELEASED_BY = ? 
     AND (
           (
            DatePart('m', sub.RELEASED_DATE) = DatePart('m', Date()) - 1
            AND DatePart('yyyy', sub.RELEASED_DATE) = DatePart('yyyy', Date())
            AND DatePart('d', sub.RELEASED_DATE) = 1
           )
          OR 
           (
            DatePart('m', sub.RELEASED_DATE) = DatePart('m', Date())
            AND DatePart('yyyy', sub.RELEASED_DATE) = DatePart('yyyy', Date())
            AND DatePart('d', sub.RELEASED_DATE) > 1
           )
        )
  )

蟒蛇

在Access引擎中传递带有日期的参数。

conn = pyodbc.connect(r'...')
insights_dbcurs = conn.cursor()

sql = """DELETE FROM RELEASES r
         WHERE r.ID IN
           (SELECT sub.ID 
            FROM RELEASES sub
            WHERE sub.RELEASED_BY = ? 
              AND (
                    (
                     DatePart('m', sub.RELEASED_DATE) = DatePart('m', Date()) - 1
                     AND DatePart('yyyy', sub.RELEASED_DATE) = DatePart('yyyy', Date())
                     AND DatePart('d', sub.RELEASED_DATE) = 1
                    )
                   OR 
                    (
                     DatePart('m', sub.RELEASED_DATE) = DatePart('m', Date())
                     AND DatePart('yyyy', sub.RELEASED_DATE) = DatePart('yyyy', Date())
                     AND DatePart('d', sub.RELEASED_DATE) > 1
                    )
                  )
           )"""

insights_dbcurs.execute(sql, ('27',))
conn.commit()
conn.close()