This question already has answers here:
How to get fields by name in query Python?
(3 answers)
Closed 3 years ago.
I would like to be able to use my SQL table in python.
I managed to connect and access my table using the code.
I would like to know if it was possible to retrieve the column names in my code.
I already have my colomns:
ACTION | MANAGER
123 XYZ
456 ABC
PersonnesQuery = "SELECT........"
cursor = mydb.cursor()
cursor.execute(PersonnesQuery)
records_Personnes = cursor.fetchall()
for row in records_Personnes:
if (row["MANAGER"] == "XYZ"):
..................
elif (row["MANAGER"] == "ABC"):
................
the way quoted does not seem to work. However, it works with the number, for example row[0]. But I would like by column name
In order to access a field by key, in this case "MANAGER", row should be a dict. But due to the fact that you can access row by index, row is type list.
Meaning you can't access by key when using .fetchall() because it returns a list.
I'm assuming you're using the pymysql library, in which case there is a specific kind of cursor called a DictCursor. This will return the results as a dictionary rather than a list.
cursor = mydb.cursor(pymysql.cursors.DictCursor)
cursor.execute(PersonnesQuery)
records_Personnes = cursor.fetchall()
Related
This question already has answers here:
Force evaluate a lazy query
(2 answers)
Closed last month.
I want to delete all the rows in a tables but before that I want to store the old data and do some operation between old and new data.
This is what I have tried.
old_data = Rc.object.all()
Rc.object.all().delete()
# Now I fetch some api and apply saving operation on table
I have noticed that data in old_data is updated to the new data.
To test this I have done some thing like this
for rows in old_data:
check = Rc.object.filter(Q(id=dt.id)&Q(modified_date__gt=rows.modified_date)).exist()
print(check)
I found check is always false (rows with that id exists in the table)
But when I print each rows in old_data just after old_data = Rc.object.all(), old_data remains same(check becomes true) and does not updated to the new data.
Is there something I am missing? How can I store all rows in the variable and then delete the rows ? Please help.
For this you need to understand how and when Django execute the command:
In your below code :
old_data = Rc.object.all()
Rc.object.all().delete()
# Now I fetch some api and apply saving operation on table
the line old_data = Rc.object.all() is just an expression and would not be executed until you are using the old_data.
For example :
if you insert the line len(old_data) or print(old_data), the values would be stored.
QuerySets are evaluated only if you "consume" the queryset.
This question already has answers here:
How do i update values in an SQL database? SQLite/Python
(5 answers)
Closed 1 year ago.
I am trying to input the score to a quiz into a database in which the user already has an account.
I am getting an error saying - "sqlite3.OperationalError: near "WHERE": syntax error"
conn.execute("INSERT INTO PlH WHERE username == (?) VALUES (?)",(username,score))
conn.commit()
The column names in the sql database are named 'PlH' and 'username' and the variables are 'score' and 'username' respectively
If I understood your question properly, you want to refresh the record in the table not to insert a new one. For this purpose you need to use UPDATE statement instead. WHERE clause of the script will be used to identify the required row (sometimes used for the list of rows updated simultaneously). SET clause wil specify the list of fields and new values to be assigned. Read SQLite documentation for the syntaxis.
This question already has answers here:
How to use variables in SQL statement in Python?
(5 answers)
Closed 2 years ago.
I have some data in an sqlite3 database, I made an input to be a command to update that data.
for some reason when I run that command it does not work and gives me an sqlite3.OperationalError: no such column: "some lettres"
my function to update the data: (the generate_pwd() function works just fine and it has been tested)
def update_query(self, wbname):
"""this function enables the user to update a query
Args:
wbname (str): the website name to change the pass
"""
with conn:
newpwd = go.generate_pwd()
c.execute(f"UPDATE password_list SET password={newpwd} WHERE website_name={wbname}")
pass
my elif statement to make the command:
elif command == "u":
wbname = input("Enter the site name: ")
co.update_query(wbname)
I hope it is clear enough, If you need any further data on my problem just type in the comments.
You can't use f-strings with SQL.
Use parametrized queries as explained in the docs instead:
c.execute(f"UPDATE password_list SET password=? WHERE website_name=?", (newpwd, wbname))
You need to wrap string values in the query within single quotes, otherwise they will be interpreted as column objects:
c.execute(f"UPDATE password_list SET password='{newpwd}' WHERE website_name='{wbname}'")
You might want to use a parameterized query instead of building a query string. That way your query is less vulnerable to SQL injections.
As parameters you can pass an interable object, e.g. a tuple or a list.
c.execute("UPDATE password_list SET password=? WHERE website_name=?", [newpwd, wbname])
You could also use named-style parameters:
c.execute("UPDATE password_list SET password=:pw WHERE website_name=:wbname", {"pw": newpwd, "wbname": wbname})
Another advantage of using parameterized queries is that you do not have to worry about wrapping strings in single quotes.
This question already has answers here:
How do you escape strings for SQLite table/column names in Python?
(8 answers)
Closed 7 years ago.
I have a wide table in a sqlite3 database, and I wish to dynamically query certain columns in a Python script. I know that it's bad to inject parameters by string concatenation, so I tried to use parameter substitution instead.
I find that, when I use parameter substitution to supply a column name, I get unexpected results. A minimal example:
import sqlite3 as lite
db = lite.connect("mre.sqlite")
c = db.cursor()
# Insert some dummy rows
c.execute("CREATE TABLE trouble (value real)")
c.execute("INSERT INTO trouble (value) VALUES (2)")
c.execute("INSERT INTO trouble (value) VALUES (4)")
db.commit()
for row in c.execute("SELECT AVG(value) FROM trouble"):
print row # Returns 3
for row in c.execute("SELECT AVG(:name) FROM trouble", {"name" : "value"}):
print row # Returns 0
db.close()
Is there a better way to accomplish this than simply injecting a column name into a string and running it?
As Rob just indicated in his comment, there was a related SO post that contains my answer. These substitution constructions are called "placeholders," which is why I did not find the answer on SO initially. There is no placeholder pattern for column names, because dynamically specifying columns is not a code safety issue:
It comes down to what "safe" means. The conventional wisdom is that
using normal python string manipulation to put values into your
queries is not "safe". This is because there are all sorts of things
that can go wrong if you do that, and such data very often comes from
the user and is not in your control. You need a 100% reliable way of
escaping these values properly so that a user cannot inject SQL in a
data value and have the database execute it. So the library writers do
this job; you never should.
If, however, you're writing generic helper code to operate on things
in databases, then these considerations don't apply as much. You are
implicitly giving anyone who can call such code access to everything
in the database; that's the point of the helper code. So now the
safety concern is making sure that user-generated data can never be
used in such code. This is a general security issue in coding, and is
just the same problem as blindly execing a user-input string. It's a
distinct issue from inserting values into your queries, because there
you want to be able to safely handle user-input data.
So, the solution is that there is no problem in the first place: inject the values using string formatting, be happy, and move on with your life.
Why not use string formatting?
for row in c.execute("SELECT AVG({name}) FROM trouble".format(**{"name" : "value"})):
print row # => (3.0,)
This question already has answers here:
imploding a list for use in a python MySQLDB IN clause
(8 answers)
Closed 1 year ago.
I want to insert a list in my database but I can't.
Here is an example of what I need:
variable_1 = "HELLO"
variable_2 = "ADIOS"
list = [variable_1,variable_2]
INSERT INTO table VALUES ('%s') % list
Can something like this be done? Can I insert a list as a value?
When I try it, an error says that is because of an error in MySQL syntax
The answer to your original question is: No, you can't insert a list like that.
However, with some tweaking, you could make that code work by using %r and passing in a tuple:
variable_1 = "HELLO"
variable_2 = "ADIOS"
varlist = [variable_1, variable_2]
print "INSERT INTO table VALUES %r;" % (tuple(varlist),)
Unfortunately, that style of variable insertion leaves your code vulnerable to SQL injection attacks.
Instead, we recommend using Python's DB API and building a customized query string with multiple question marks for the data to be inserted:
variable_1 = "HELLO"
variable_2 = "ADIOS"
varlist = [variable_1,variable_2]
var_string = ', '.join('?' * len(varlist))
query_string = 'INSERT INTO table VALUES (%s);' % var_string
cursor.execute(query_string, varlist)
The example at the beginning of the SQLite3 docs shows how to pass arguments using the question marks and it explains why they are necessary (essentially, it assures correct quoting of your variables).
Your question is not clear.
Do you want to insert the list as a comma-delimited text string into a single column in the database? Or do you want to insert each element into a separate column? Either is possible, but the technique is different.
Insert comma-delimited list into one column:
conn.execute('INSERT INTO table (ColName) VALUES (?);', [','.join(list)])
Insert into separate columns:
params = ['?' for item in list]
sql = 'INSERT INTO table (Col1, Col2. . .) VALUES (%s);' % ','.join(params)
conn.execute(sql, list)
both assuming you have established a connection name conn.
A few other suggestions:
Try to avoid INSERT statements that do not list the names and order of the columns you're inserting into. That kind of statement leads to very fragile code; it breaks if you add, delete, or move columns around in your table.
If you're inserting a comma-separted list into a single-field, that generally violates principals of database design and you should use a separate table with one value per record.
If you're inserting into separate fields and they have names like Word1 and Word2, that is likewise an indication that you should be using a separate table instead.
Never use direct string substitution to create SQL statements. It will break if one of the values is, for example o'clock. It also opens you to attacks by people using SQL injection techniques.
You can use json.dumps to convert a list to json and write the json to db.
For example:
insert table example_table(column_name) values(json.dumps(your_list))