用于减少读取sqlite3中数据库的冗余的函数

2024-09-27 21:23:56 发布

您现在位置:Python中文网/ 问答频道 /正文

大家好:)我是一个编程新手,我想在创建一个函数以减少代码冗余方面寻求帮助。我已经成功地创建了一个数据库,其中包含5个不同国家的数据表。所有表格都具有相同的结构(请参见随附的屏幕截图以供参考)。我的目标是计算特定参数(污染类型)所有不同表中所有行的总和。 我已经成功地编写了代码,只选择了一个国家需要的特定数据(我试图编写代码来计算总和,但我想不出来,所以我决定只选择数据,然后自己用计算器手动计算值-我知道这有点违背编程的目的,但在我的编程级别上(初学者)我觉得这是我编写代码的唯一方法)我的问题是我有五个国家,所以我不想为不同的国家重复相同的代码块。这是我为一个国家编写的代码:

def read_MaltaData():
    conn = sqlite3.connect('FinalProjectDatabase.sqlite3')
    Malta = conn.cursor()
    Malta.execute("SELECT * FROM MaltaData WHERE AirPollutant = 'PM10'")
    result = Malta.fetchall()
    print(result)

我的结果是:

[('Malta', 'Valletta', 'MT00005', 'Msida', 'PM10', 64.3, 'ug/m3', 'Traffic', 'urban', 14.489985999999998, 35.895835999489535, 2.0), ('Malta', None,

(我将手动计算我需要的数据——在本例中为64.3+下一行的值——因为我不知道如何在python中进行计算)

澄清一下,我的目标不是将所有表格的总和作为一个整体值(即,我不想将所有国家的值加在一起)。我想要的输出应该如下所示:

Malta    summation value
italy    summation value
france   summation value

而不是像这样

所有国家=一个整数值(即所有总和加在一起)

我将非常感谢任何我能得到的帮助。不幸的是,我不能与你共享数据库,这就是为什么我要共享它的截图

一个数据库中所有5个不同表的图像: enter image description here

一个表的图像(所有表看起来相同,只是值不同) enter image description here


Tags: 数据代码数据库目标value编程手动国家
3条回答

如果将国家名称作为参数传递给数据检索函数,则可以动态生成表名(请注意executeprint中的f-string参数):

初稿

def print_CountryData(country):
    conn = sqlite3.connect('FinalProjectDatabase.sqlite3')
    cur = conn.cursor()
    cur.execute(f"SELECT SUM(AirPollutionLevel) FROM {country}Data WHERE AirPollutant = 'PM10'")
    sumVal = cur.fetchone()[0]
    print(f"{country} {sumVal}")

# example call:
for country in ('France', 'Germany', 'Italy', 'Malta', 'Poland'):
    print_CountryData(country)
在构建查询字符串时,出于安全原因,在简单的字符串函数中,您自己在sqlite3 documentation中被阻止,在您完全控制实际参数的情况下,我认为它是安全的。p>

这个答案调整了great answer given by forpas的求和,但拒绝将重复移动到SQL。它还显示了与python的集成和输出格式

MRE样式版本

这是我第一个答案的改进版本,转换为Minimal, Reproducible Example并与输出相结合。此外,还进行了一些性能改进,例如只打开数据库一次

import sqlite3
import random # to simulate actual pollution values

# Countries we have data for
countries = ('France', 'Germany', 'Italy', 'Malta', 'Poland')

# There is one table for each country
def tableName(country):
    return country+'Data'

# Generate minimal version of tables filled with random data
def setup_CountryData(cur):
    for country in countries:
        cur.execute(f'''CREATE TABLE {tableName(country)}
                (AirPollutant text, AirPollutionLevel real)''')
        for i in range(5):
            cur.execute(f"""INSERT INTO {tableName(country)} VALUES 
                    ('PM10', {100*random.random()})""")
                    
# Get sum up pollution data for each country
def print_CountryData(cur):
    for country in countries:
        cur.execute(f"""SELECT SUM(AirPollutionLevel) FROM 
                {tableName(country)} WHERE AirPollutant = 'PM10'""")
        sumVal = cur.fetchone()[0]
        print(f"{country:10} {sumVal:9.5f}")

# For testing, we use an in-memory database
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
setup_CountryData(cur)

# The functionality actually required
print_CountryData(cur)

样本输出:

France     263.79430
Germany    245.20942
Italy      225.72068
Malta      167.72690
Poland     290.64190

在没有实际尝试的情况下,通常很难评估解决方案。这就是为什么StackOverflow上的提问者不断被鼓励以这种方式提问的原因:这使得有人更可能理解并解决问题快速

如果数据库不是太大,可以使用^{}

与直接使用SQL查询相比,这种方法效率较低,但如果您希望以交互方式在笔记本中浏览数据,则可以使用这种方法

您可以使用^{}从SQLite数据库创建数据帧

然后使用为此类任务设计的pandas.DataFrame方法执行计算

针对您的具体情况:

import sqlite3
import pandas as pd

conn = sqlite3.connect(db_file)

query = "SELECT * FROM MaltaData WHERE AirPollutant = 'PM10'"
df = pd.read_sql_query(query, conn)

# check dataframe content
print(df.head())

如果我理解了,然后您想计算给定列中的值之和:

s = df['AirPollutionLevel'].sum()

如果缺少值,则可能需要在求和之前用0填充:

s = df['AirPollutionLevel'].fillna(0).sum()

可以使用UNION ALL为每个国家/地区获取一行:

SELECT 'France' country, SUM(AirPolutionLevel) [summation value] FROM FranceData WHERE AirPollutant = 'PM10'
UNION ALL
SELECT 'Germany' country, SUM(AirPolutionLevel) [summation value] FROM GermanyData WHERE AirPollutant = 'PM10'
UNION ALL
SELECT 'Italy' country, SUM(AirPolutionLevel) [summation value] FROM ItalyData WHERE AirPollutant = 'PM10'
UNION ALL
SELECT 'Malta' country, SUM(AirPolutionLevel) [summation value] FROM MaltaData WHERE AirPollutant = 'PM10'
UNION ALL
SELECT 'Poland' country, SUM(AirPolutionLevel) [summation value] FROM PolandData WHERE AirPollutant = 'PM10'

相关问题 更多 >

    热门问题