In an effort to learn SQL I've been using it at work. I keep a list of every account I work on and the information I gather while working on that particular account. My database has two tables that I update. One is the customer's information and it always gets updated with each new account and the other is an institution table that gets updated sometimes but not every time. These two tables are relational.
As I said, I am new to SQL and have been using the command line to update these tables and it's getting annoying. What I thought would be an easy solution is to run a series of Python prompts that queries the user for each column and then executes the INSERT command at the end of the prompt. It would then ask if I wanted to create an entry for the second table (since I don't always add to this one).
These are my tables.
> create table stu_info (
> id Integer,
> name text,
> CEEB integer,
> degree text,
> terms integer,
> comm text
> );
> create table coll_info (
> CEEB integer,
> name text,
> Accred text,
> Hours text,
> comm text
> );
In Python I figure it'd be easy to just use raw_input() and add an int() around it when required. Then use a loop so that after adding each new row to the database it starts over until I'm done for the day. My problem is I cannot figure out how to execute sqlite commands through Python and I can't figure out how to access the database.
Whenever I run
import sqlite3
conn = sqlite3.connect(stu.db)
c = conn.cursor()
enter code here
I get a NameError: name 'stu' is not defined
Any help? I imagine this is easy and my Google-fu is bad and inexperience has led even good search results to being useless...
It looks like it's as simple as needing quotes.
conn = sqlite3.connect("stu.db")
The error you're getting is because there is no variable stu in scope. So long as "stu.db" is in the working directory then the snippet above should work.
Once I found out, thanks to Jamie, that the filename needs to be in quotes I was able to connect to the database. I then was able to work my way through the problem. Here is my solution:
import sqlite3
conn = sqlite3.connect('stu.db')
c = conn.cursor()
def add_coll():
cceeb = int(raw_input("CEEB:> "))
cname = raw_input("Name:> ")
ccred = raw_input("Accred:> ")
ccal = raw_input("Calendar:> ")
ccomm = raw_input("Comments:> ")
c.execute("INSERT INTO coll VALUES (%d, '%s', '%s', '%s', '%s')" %
(cceeb, cname, ccred, ccal, ccomm))
var = 1 #This creates an infinite loop
while var == 1:
input_stu = raw_input("Add Student?:> ")
if input_stu == 'no' or input_stu == 'n':
add_coll()
else:
id = int(raw_input("ID:> "))
name = raw_input("Name:> ")
ceeb = int(raw_input("CEEB:> "))
deg = raw_input("Degree:> ")
terms = int(raw_input("Terms:> "))
comm = raw_input("Comments:> ")
c.execute("INSERT INTO stu VALUES (%d, '%s', %d, '%s', %d, '%s')" %
(id, name, ceeb, deg, terms, comm))
input_coll = raw_input("Add College?:> ")
if input_coll == 'yes' or input_coll == 'y':
#cceeb = int(raw_input("CEEB:> "))
#cname = raw_input("Name:> ")
#ccred = raw_input("Accred:> ")
#ccal = raw_input("Calendar:> ")
#
#c.execute("INSERT INTO coll VALUES (%d, '%s', '%s', '%s')" %
# (cceeb, cname, ccred, ccal))
add_coll()
conn.commit()
Related
I am trying to create a command line tool that generates a random string(password) of a given length, stores it in a sql db, and can be queried by name. The password generation and storing of it's output by a given name works beautifully, but trying to select only the password element is giving me trouble. I was able to select all from the table but that returns the name and the password. I only want the password returned. I thought about just splicing the output or even using the linux cut command, but I'd rather just get it from the select statement. Is this possible? My current SELECT statement returns: operation parameter must be a str. When I try it without the call to (name) at the end of the SELECT statement like this: query_password = """SELECT * FROM password_table WHERE name = ?"""
I get this error:
File "passbox.py", line 44, in <module>
query_pswd_by_name(name)
File "passbox.py", line 39, in query_pswd_by_name
c.execute(query_password)
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 0 supplied.
BTW I'm sure my query_pswd_by_name function is all wrong, I've been experimenting. When I just create a connection and SELECT statement outside of a function it does return the name and password.
Also note that I've disguised my database file's name with asterisks for the purpose of this post. I am using an actual working db file in practice.
Here is all the code I've written so far:
import secrets
import string
import sqlite3
#CREATE PASSWORD OF GIVEN LENGTH
def get_pass(length):
return "".join(secrets.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits + string.punctuation) for x in range(length))
length = int(input("Enter the length of password: "))
password= get_pass(length)
print(password)
name = str(input("Enter name for password: "))
#CREATE DATABASE CONNECTION
conn = sqlite3.connect("****.db")
#CREATE CURSOR OBJECT
c = conn.cursor()
#CREATE TABLE IN DISK FILE BASED DATABASE
c.execute("""CREATE TABLE IF NOT EXISTS password_table (
name TEXT,
pswd TEXT
)""")
c.execute("INSERT INTO password_table (name, pswd) VALUES (?, ?)", (name, password))
#COMMIT CHANGES
conn.commit()
conn.close()
def query_pswd_by_name(name):
conn = sqlite3.connect('****.db')
c = conn.cursor()
query_password = """SELECT * FROM password_table WHERE name = ?""", (name)
c.execute(query_password)
result = c.fetchall()
for row in result:
print(row[1])
conn.commit()
query_pswd_by_name(name)
#CLOSE CONNECTION
conn.close()```
You need to break up the argument to the execute call.
c.execute(*query_password)
Or
c.execute("""SELECT * FROM password_table WHERE name = ?""", (name))
I want to search a mysql table for rows where the specified column has a particular value. For example, given the input string memory=2048 it will search for the rows that have "2048" as the value of memory column and it will print them.
This is code that I have tried but it print outs nothing.
input = input()
tag = input.split("=")
desc = tag[1]
tag = tag[0]
mycursor = mydb.cursor()
sql = "(SELECT * FROM comp WHERE %s LIKE %s)"
val = (tag, desc)
mycursor.execute(sql, val)
res = mycursor.fetchall()
for x in res:
print(x)
Secondly I tried this code to see where is the problem :
input = input()
tag = input.split("=")
desc = tag[1]
tag = tag[0]
mycursor = mydb.cursor()
sql = "(SELECT * FROM comp WHERE memory LIKE '2048')"
mycursor.execute(sql)
res = mycursor.fetchall()
for x in res:
print(x)
It gives the desired output. So my problem is when I am trying to get the column name with %s it comes as 'memory' and It couldn't finds it, since the name of the column is memory. Is there a way to get rid of the '' chars ?
confirmation of inputs
Looking at the mysql.connector's execute() documentation it appears to use %s as placeholders for bind parameters.
So your execute("SELECT * FROM comp WHERE %s LIKE %s", ("memory", "2048")) call ends up running like the following SQL:
SELECT * FROM comp WHERE 'memory' LIKE '2048'
obviously returning 0 rows.
You need to put the literal column name into the query text before invoking execute():
sql = "SELECT * FROM comp WHERE %s LIKE %s" % (tag, "%s")
# => "SELECT * FROM comp WHERE memory LIKE %s"
mycursor.execute(sql, (desc, ))
I have a program that currently reads a database and it will print out the list of tables the current database has.
This is the DB LINK: database (Copy and Paste)
What I am trying to do now is to get user input to display the records from the specific table they chose. I am having trouble to get user selection to display the records. I am using SQLite3 as my main database software.
Also I am very aware of this question on here, but
I keep getting an error when I used the .format(category) embedded on my SQL.
sqlite3.ProgrammingError:
Incorrect number of bindings supplied.
The current statement uses 1, and there are 0 supplied.
This is what I have done so far:
import sqlite3
def get_data():
print("\nSelect a table: ", end="")
category = input()
category = str(category)
if '1' <= category <= '11':
print()
return category
else:
raise ValueError
def get_tables():
database = 'Northwind.db'
connection = sqlite3.connect(database)
c = connection.cursor()
sql = "SELECT * FROM sqlite_master WHERE type='table' AND NAME NOT LIKE 'sqlite_sequence' ORDER BY NAME "
x = c.execute(sql)
for row in x.fetchall():
table = row[1]
print(table)
def main():
category = get_data()
print(category)
get_tables()
if __name__ == "__main__":
main()
I hope this all makes sense. I appreciate the help.
Copy comment: My sql statement look like this:
*)multiple lines for readability
sql = ("SELECT * FROM sqlite_master
WHERE type='table'
AND Name = ?
AND NAME NOT LIKE 'sqlite_sequence'".format(category))
Your SQL string should be:
sql = """SELECT * FROM sqlite_master
WHERE type='table'
AND Name = ?
AND NAME NOT LIKE 'sqlite_sequence'"""
and the execute statement should be:
x = c.execute(sql, (category,))
also ensure that you are passing category as a parameter to your get_tables function.
I scripted in Python SQL calls to my MonetDB server (which I verify is running, of course). When I print the calls instead of calling them, the commands look OK, but if I run the original script, it does not crash, it does use the CPU and memory, but nothing is changed in the database, not even the first line is executed. Why?
The Python script looks like this:
# script to merge tables in MonetDB
import re
from monetdb import mapi
server = mapi.Server()
server.connect(hostname="localhost", port=50000, username="monetdb", password="monetdb", database="dbfarm", language="sql")
def tablemerge(stub,yearlist):
for year in yearlist:
# server.cmd('ALTER TABLE %s_%d ADD COLUMN "year" INTEGER DEFAULT %d;' % (stub,year,year))
print 'ALTER TABLE %s_%d ADD COLUMN "year" INTEGER DEFAULT %d;' % (stub,year,year)
newstub = re.sub(r'sys.ds_chocker_lev_', r'', stub)
if year == yearlist[0]:
unioncall = 'CREATE TABLE %s AS SELECT * FROM %s_%d ' % (newstub,stub,year)
else:
unioncall += 'UNION ALL SELECT * FROM %s_%d ' % (stub,year)
unioncall += ';'
server.cmd(unioncall)
# print unioncall
for year in yearlist:
server.cmd('DROP TABLE %s_%d;' % (stub,year))
# print 'DROP TABLE %s_%d;' % (stub,year)
print '%s done.' % stub
for stub in ['civandr']:
tablemerge('sys.ds_chocker_lev_%s' % stub,xrange(1998,2013))
E.g. the first call would be:
ALTER TABLE sys.ds_chocker_lev_civandr_1998 ADD COLUMN "year" INTEGER DEFAULT 1998;
But not even this happens. There is no year column in the table.
Or could I run the script in the console with more output than what I print myself?
Do commit! By default, the autocommit parameter is set to False. You can either do:
server.connect(hostname="localhost", port=50000, username="monetdb", password="monetdb", database="dbfarm", language="sql", autocommit=True)
or simply run:
connection.commit()
connection = monetdb.sql.connect(username=username,password=password,hostname=hostname,port=port,database=database)
cursor = connection.cursor()
cursor.execute('create table test (id int, name varchar(50));')
connection.commit()
I get the error when running this code:
import sqlite3
user_name = raw_input("Please enter the name: ")
user_email = raw_input("Please enter the email: ")
db = sqlite3.connect("customer")
cursor=db.cursor()
sql = """INSERT INTO customer
(name, email) VALUES (?,?);,
(user_name, user_email)"""
cursor.execute(sql)
Why is this happening?
While the other posters are correct about your statement formatting you are receiving this particular error because you are attempting to perform multiple statements in one query (notice the ; in your query which separates statements).
From Python sqlite3 docs:
"execute() will only execute a single SQL statement. If you try to execute more than one
statement with it, it will raise a Warning. Use executescript() if you want to execute
multiple SQL statements with one call."
https://docs.python.org/2/library/sqlite3.html
Now your statement will not execute properly even if you use executescript() because there are other issues with the way it is formatted (see other posted answers). But the error you are receiving is specifically because of your multiple statements. I am posting this answer for others that may have wandered here after searching for that error.
Use executescript instead of execute
execute() will only execute a single SQL statement. If you try to execute more than one statement with it, it will raise a Warning. Use executescript() if you want to execute multiple SQL statements with one call.
https://docs.python.org/2/library/sqlite3.html#sqlite3.Cursor.execute
You have a ;, in the middle of the query string - that is an invalid syntax. Pass a dictionary as a second argument to execute if you want to use a named parameter binding.
sql = "INSERT INTO customer (name, email) VALUES (:name, :email)"
cursor.execute(sql, {'name':user_name, 'email':user_email})
Try this:
sql = """INSERT INTO customer
(name, email) VALUES (?,?)"""
cursor.execute(sql, (user_name, user_email))
import sqlite3
def DB():
List = {"Name":"Omar", "Age":"33"}
columns = ', '.join("" + str(x).replace('/', '_') + "" for x in List.keys())
values = ', '.join("'" + str(x).replace('/', '_') + "'" for x in List.values())
sql_qry = "INSERT INTO %s ( %s ) values (?,?) ; ( %s )" % ('Table Name', columns, values)
conn = sqlite3.connect("DBname.db")
curr = conn.cursor()
# curr.execute("""create table if not exists TestTable(
# Name text,
# Age text
# )""")
# print columns
# print values
# print sql
# sql = 'INSERT INTO yell (Name , Age) values (%s, %s)'
curr.execute(sql_qry)
DB()