简体   繁体   中英

Translating a complicated SQL query to python 2 for SQLite3

Below I have some code that connects to database and runs a query. This query runs as expected if I punch it into DB Browser for SQLite, but when I run it in python, I receive the error :

sqlite3.OperationalError: no such column: CHARACTER_INNATES.PC_ID

I have read some documentation and multiple StackOverflow comments about parameters, and their purpose to prevent problems like injection attacks. I tried that approach, which littered '?' everywhere, making it unreadable and unmaintainable, and it didn't work. It returned an empty tuple. This leads me to believe there should be an easier way of performing these kinds of SQL queries. So is there? Or am I missing something obvious?

db = sqlite3.connect('TheGame.db')
db.text_factory = str
conn = db.cursor()
query = 'SELECT CHARACTERS.Full_Name, CHARACTER_INNATES.PC_ID, SKILLS_INNATES.Skill, Sum([CHARACTER_INNATES].[Current]*[Weight]) AS [Current Innate], Sum([CHARACTER_INNATES].[Maximum]*[Weight]) AS [Max Innate]\
      FROM CHARACTERS INNER JOIN (SKILLS_INNATES INNER JOIN CHARACTER_INNATES ON SKILLS_INNATES.Innate = CHARACTER_INNATES.Innate) ON CHARACTERS.ID = CHARACTER_INNATES.PC_ID\
      GROUP BY CHARACTERS.Full_Name, CHARACTER_INNATES.PC_ID, SKILLS_INNATES.Skill\
      ORDER BY CHARACTER_INNATES.PC_ID, Sum([CHARACTER_INNATES].[Current]*[Weight]) DESC;'
conn.execute(query)
print conn.fetchall()

My attempt at a fix looked something like

params = ('CHARACTERS.Full_Name', 'CHARACTER_INNATES.PC_ID', ...) #this continued for awhile
query = 'SELECT ?, ?, ?, ...'
conn.execute(query, params)
print conn.fetchall() # prints empty tuple

This query already is unreadable.

Anyway, some SQLite versions have problem with table names hidden inside parentheses. This typically happens when you're using the Access query builder; just write the joins properly instead:

SELECT CHARACTERS.Full_Name,
       CHARACTER_INNATES.PC_ID,
       SKILLS_INNATES.Skill,
       Sum(CHARACTER_INNATES.Current * Weight) AS "Current Innate",
       Sum(CHARACTER_INNATES.Maximum * Weight) AS "Max Innate"
FROM CHARACTERS
INNER JOIN CHARACTER_INNATES ON CHARACTERS.ID = CHARACTER_INNATES.PC_ID
INNER JOIN SKILLS_INNATES USING (Innate)
GROUP BY CHARACTERS.Full_Name,
         CHARACTER_INNATES.PC_ID,
         SKILLS_INNATES.Skill
ORDER BY CHARACTER_INNATES.PC_ID,
         Sum(CHARACTER_INNATES.Current * Weight) DESC;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM