簡體   English   中英

function 減少在 sqlite3 中讀取數據庫的冗余

[英]function to reduce redundancy for reading database in sqlite3

大家好:)我是編程新手,想在創建 function 以幫助減少代碼中的冗余方面尋求幫助。 我已經成功創建了一個數據庫,其中包含 5 個不同國家的數據表。 所有表格都具有相同的結構(請參閱隨附的屏幕截圖以供參考)。 我的目標是針對特定參數(污染類型)計算所有不同表中所有行的總和。 我已經設法僅將代碼寫入 select 我需要一個國家的特定數據(我嘗試編寫代碼來計算總和但我無法弄清楚,所以我決定只使用 select 數據,然后自己手動計算值用計算器 - 我知道這有點違背編程的目的,但在我的編程水平(初學者)我覺得這是我可以編寫代碼的唯一方法)我的問題是我有五個國家,所以我不想為不同的國家重復相同的代碼塊。 這是我對一個國家的代碼:

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 中執行此操作)

澄清一下,我的目標不是將所有表格的總和作為一個整體值(即我不想將所有國家的值加在一起)。 我想要的 output 應該是這樣的:

Malta    summation value
italy    summation value
france   summation value

而不是這樣

國家加在一起 = 一個整數(即所有總和值加在一起)

我將非常感謝我能得到的任何幫助。 不幸的是,我無法與您共享數據庫,這就是為什么我要共享它的屏幕截圖。

一個數據庫中所有 5 個不同表的圖像: 在此處輸入圖像描述

一張表的圖片(所有表看起來都一樣,只是值不同) 在此處輸入圖像描述

您可以使用 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'

如果將國家名稱作為參數傳遞給數據檢索 function,則可以動態生成表名(注意executeprint中的f 字符串arguments):

第一稿

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 文檔中不鼓勵使用簡單的字符串函數構建您自己的查詢字符串,但在您完全控制實際 arguments 的情況下,我認為它是安全的。

這個答案改編了forpas給出的好答案的總和,但拒絕將重復移動到SQL。 它還顯示了與 python 和 output 格式的集成。

MRE 風格版本

這是我的第一個答案的改進版本,已轉換為最小的、可重現的示例,並與 output 結合使用。 此外,還進行了一些性能改進,例如只打開一次數據庫。

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)

樣品 output:

France     263.79430
Germany    245.20942
Italy      225.72068
Malta      167.72690
Poland     290.64190

如果不實際嘗試,通常很難評估解決方案。 這就是為什么 StackOverflow 上的提問者經常被鼓勵以這種方式提問的原因:它使人們更有可能理解並解決問題......快速

如果數據庫不是太大,您可以使用pandas

這種方法比直接使用 SQL 查詢效率低,但如果您想在筆記本中以交互方式探索數據,則可以使用這種方法。

您可以使用 pandas.read_sql_query 從 SQLite 數據庫創建pandas.read_sql_query

然后使用專為此類任務設計的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()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM