I am trying to make a random code generator in python that writes to a database. I have the codes generating and writing to the database, but instead of adding full codes to the database it loops through letters. Here is my code for the code generator:
import string
import random
import sqlite3
def id_generator():
db = sqlite3.connect('codes.db')
c = db.cursor()
number_of_codes = 10
stringLength = 9
id_code = input("what letter should this begin with: \n")
id_code = id_code.upper()
dict_ofcodes = []
for x in range(0, number_of_codes):
codez = (''.join(random.choice(string.ascii_uppercase) for i in range(stringLength)))
final_codez = (id_code + codez)
dict_ofcodes.insert(x, final_codez)
print (dict_ofcodes)
dict_ofcodes_tuple = tuple(dict_ofcodes)
print(dict_ofcodes_tuple)
for x in range(0, number_of_codes):
c.executemany(''' INSERT INTO codes(codes) VALUES(?)''', dict_ofcodes_tuple[x])
db.commit()
db.close()
id_generator()
Here is what it prints
['AALRRIULNC', 'AZTKZBKTLK', 'ATWMWYWICO', 'AWQJIJYEJH', 'AQFIONPUNJ', 'AMJRXUIJXM', 'AUDRLSBLSG', 'ABXYXDUMPD', 'AUAXRQURBH', 'ADQEVIRDFU']
('AALRRIULNC', 'AZTKZBKTLK', 'ATWMWYWICO', 'AWQJIJYEJH', 'AQFIONPUNJ', 'AMJRXUIJXM', 'AUDRLSBLSG', 'ABXYXDUMPD', 'AUAXRQURBH', 'ADQEVIRDFU')
It writes to the database single letters of the codes:
A
F
Y
and so on
The code I used to create the schema is contained in the a python file
import sqlite3
def writeDB():
db = sqlite3.connect('codes.db')
c = db.cursor()
# Create table
c.execute('''CREATE TABLE codes (codes TEXT)''')
# Save (commit) the changes
db.commit()
#can also close the connection if done with it.
# be sure any changes have been committed or they will be lost.
db.close()
writeDB()
I created the file with the mac terminal.
How could I write the full codes to the database?
The problem is with this line:
c.executemany(''' INSERT INTO codes(codes) VALUES(?)''', dict_ofcodes_tuple[x])
executemany is used to iterate over a list of parameters and call the sql statement for each parameter. So your dict_ofcodes_tupel[x] is treated as a character array and the INSERT is called for each character.
If you want to insert the entire string as one, use execute() instead.
c.execute(''' INSERT INTO codes(codes) VALUES(?)''', (dict_ofcodes_tuple[x],))
or
c.execute(''' INSERT INTO codes(codes) VALUES(?)''', [dict_ofcodes_tuple[x]])
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 am trying to pass a variable to search for the row from SQLite DB and print out the results. Here is the code below thats causing the problem:
find_domain = 'domain.com'
def searchdomain(locate):
row = sql.execute("SELECT * FROM blocked_domains WHERE name = ?;",(locate,))
print(row)
searchdomain(find_domain)
No error comes up, it just come back blank.
Ensure that you have created a cursor object for data retrieval:
import sqlite3
conn = sqlite3.connect('tablename.db')
data = list(conn.cursor().execute("SELECT * FROM blocked_domains WHERE name = ?;", (locate,)))
I'm busy writting a python script that is querying two db tables to build a single row of data per row it finds. Here is my script at the moment
#========================================================================
# DB CONNECT FUNCTION
#========================================================================
def f_connect(status):
global gv_conn
global gv_curs
if status == 1:
gv_conn = sqlite3.connect("./data.db")
gv_curs = gv_conn.cursor()
else
gv_conn.close()
#========================================================================
# PREPARE SQL STATEMENTS
#========================================================================
def f_statements():
global users_stmt
users_stmt = ("select * from users")
global users_curs
users_curs = gv_conn.cursor()
global uinfo_stmt
uinfo_stmt = ("select * from uinfo" +
"where ui_u_id = ?")
global uinfo_curs
uinfo_curs = gv_conn.cursor()
#========================================================================
#
# MAIN SCRIPT START
#
#========================================================================
f_connect(1)
f_statements()
la_users = []
for u_row in users_curs.execute(users_stmt):
# THIS LINE GETS USERS FROM THE ABOVE STATEMENT
# AND ADDS THEM TO THE DICTIONARY
la_users.append({"u_id": u_row[0], "u_name": u_row[1]})
# THIS LINE EXECUTES ANOTHER QUERY TO RETRIEVE
# A SINGLE ROW OF DATA FROM ANOTHER TABLE
la_uinfo = uinfo_curs.execute(uinfo_stmt, "1")
f_connect(0)
My problem is that when I execute the first sql statement I can get get the data by looping using a for loop which is storing the data so i can access it using u_row[int].
When I execute the second query it is storing it inside la_uinfo although when I try to get the data from la_uinfo[int] it doesn't work? How can I retrieve the data from my second query without using another for loop? (I shouldn't have to considering it only returns one row)
Cursors are not indexable, so cursor[0] will not work. To retrieve the first row of a cursor, you should use cursor.fetchone().
I am working on a learning how to execute SQL in python (I know SQL, not Python).
I have an external sql file. It creates and inserts data into three tables 'Zookeeper', 'Handles', 'Animal'.
Then I have a series of queries to run off the tables. The below queries are in the zookeeper.sql file that I load in at the top of the python script. Example for the first two are:
--1.1
SELECT ANAME,zookeepid
FROM ANIMAL, HANDLES
WHERE AID=ANIMALID;
--1.2
SELECT ZNAME, SUM(TIMETOFEED)
FROM ZOOKEEPER, ANIMAL, HANDLES
WHERE AID=ANIMALID AND ZOOKEEPID=ZID
GROUP BY zookeeper.zname;
These all execute fine in SQL. Now I need to execute them from within Python. I have been given and completed code to read in the file. Then execute all the queries in the loop.
The 1.1 and 1.2 is where I am getting confused. I believe in the loop this is the line where I should put in something to run the first and then second query.
result = c.execute("SELECT * FROM %s;" % table);
but what? I think I am missing something very obvious. I think what is throwing me off is % table. In query 1.1 and 1.2, I am not creating a table, but rather looking for a query result.
My entire python code is below.
import sqlite3
from sqlite3 import OperationalError
conn = sqlite3.connect('csc455_HW3.db')
c = conn.cursor()
# Open and read the file as a single buffer
fd = open('ZooDatabase.sql', 'r')
sqlFile = fd.read()
fd.close()
# all SQL commands (split on ';')
sqlCommands = sqlFile.split(';')
# Execute every command from the input file
for command in sqlCommands:
# This will skip and report errors
# For example, if the tables do not yet exist, this will skip over
# the DROP TABLE commands
try:
c.execute(command)
except OperationalError, msg:
print "Command skipped: ", msg
# For each of the 3 tables, query the database and print the contents
for table in ['ZooKeeper', 'Animal', 'Handles']:
**# Plug in the name of the table into SELECT * query
result = c.execute("SELECT * FROM %s;" % table);**
# Get all rows.
rows = result.fetchall();
# \n represents an end-of-line
print "\n--- TABLE ", table, "\n"
# This will print the name of the columns, padding each name up
# to 22 characters. Note that comma at the end prevents new lines
for desc in result.description:
print desc[0].rjust(22, ' '),
# End the line with column names
print ""
for row in rows:
for value in row:
# Print each value, padding it up with ' ' to 22 characters on the right
print str(value).rjust(22, ' '),
# End the values from the row
print ""
c.close()
conn.close()
Your code already contains a beautiful way to execute all statements from a specified sql file
# Open and read the file as a single buffer
fd = open('ZooDatabase.sql', 'r')
sqlFile = fd.read()
fd.close()
# all SQL commands (split on ';')
sqlCommands = sqlFile.split(';')
# Execute every command from the input file
for command in sqlCommands:
# This will skip and report errors
# For example, if the tables do not yet exist, this will skip over
# the DROP TABLE commands
try:
c.execute(command)
except OperationalError, msg:
print("Command skipped: ", msg)
Wrap this in a function and you can reuse it.
def executeScriptsFromFile(filename):
# Open and read the file as a single buffer
fd = open(filename, 'r')
sqlFile = fd.read()
fd.close()
# all SQL commands (split on ';')
sqlCommands = sqlFile.split(';')
# Execute every command from the input file
for command in sqlCommands:
# This will skip and report errors
# For example, if the tables do not yet exist, this will skip over
# the DROP TABLE commands
try:
c.execute(command)
except OperationalError, msg:
print("Command skipped: ", msg)
To use it
executeScriptsFromFile('zookeeper.sql')
You said you were confused by
result = c.execute("SELECT * FROM %s;" % table);
In Python, you can add stuff to a string by using something called string formatting.
You have a string "Some string with %s" with %s, that's a placeholder for something else. To replace the placeholder, you add % ("what you want to replace it with") after your string
ex:
a = "Hi, my name is %s and I have a %s hat" % ("Azeirah", "cool")
print(a)
>>> Hi, my name is Azeirah and I have a Cool hat
Bit of a childish example, but it should be clear.
Now, what
result = c.execute("SELECT * FROM %s;" % table);
means, is it replaces %s with the value of the table variable.
(created in)
for table in ['ZooKeeper', 'Animal', 'Handles']:
# for loop example
for fruit in ["apple", "pear", "orange"]:
print(fruit)
>>> apple
>>> pear
>>> orange
If you have any additional questions, poke me.
A very simple way to read an external script into an sqlite database in python is using executescript():
import sqlite3
conn = sqlite3.connect('csc455_HW3.db')
with open('ZooDatabase.sql', 'r') as sql_file:
conn.executescript(sql_file.read())
conn.close()
First make sure that a table exists if not, create a table then follow the steps.
import sqlite3
from sqlite3 import OperationalError
conn = sqlite3.connect('Client_DB.db')
c = conn.cursor()
def execute_sqlfile(filename):
c.execute("CREATE TABLE clients_parameters (adress text, ie text)")
#
fd = open(filename, 'r')
sqlFile = fd.readlines()
fd.close()
lvalues = [tuple(v.split(';')) for v in sqlFile[1:] ]
try:
#print(command)
c.executemany("INSERT INTO clients_parameters VALUES (?, ?)", lvalues)
except OperationalError as msg:
print ("Command skipped: ", msg)
execute_sqlfile('clients.sql')
print(c.rowcount)
according me, it is not possible
solution:
import .sql file on mysql server
after
import mysql.connector
import pandas as pd
and then you use .sql file by convert to dataframe
I'm attempting to get a python script to insert data into a database without having it drop the table first.. I'm sure this isn't hard to do but I can't seem to get the code right..
Here is the full python script..
#!/usr/bin/python
# -*- coding: utf-8 -*-
import requests
import hashlib
import time
import MySQLdb
#Dont forget to fill in PASSWORD and URL TO saveTemp (twice) in this file
sensorids = ["28-000004944b63", "28-000004c01b2c"]
avgtemperatures = []
for sensor in range(len(sensorids)):
temperatures = []
for polltime in range(0,3):
text = '';
while text.split("\n")[0].find("YES") == -1:
# Open the file that we viewed earlier so that python can see what is in it. Replace the serial number as before.
tfile = open("/sys/bus/w1/devices/"+ sensorids[sensor] +"/w1_slave")
# Read all of the text in the file.
text = tfile.read()
# Close the file now that the text has been read.
tfile.close()
time.sleep(1)
# Split the text with new lines (\n) and select the second line.
secondline = text.split("\n")[1]
# Split the line into words, referring to the spaces, and select the 10th word (counting from 0).
temperaturedata = secondline.split(" ")[9]
# The first two characters are "t=", so get rid of those and convert the temperature from a string to a number.
temperature = float(temperaturedata[2:])
# Put the decimal point in the right place and display it.
temperatures.append(temperature / 1000 * 9.0 / 5.0 + 32.0)
avgtemperatures.append(sum(temperatures) / float(len(temperatures)))
print avgtemperatures[0]
print avgtemperatures[1]
#connect to db
db = MySQLdb.connect("localhost","user","password","temps" )
#setup cursor
cursor = db.cursor()
#create temps table
cursor.execute("DROP TABLE IF EXISTS temps")
sql = """CREATE TABLE temps (
temp1 FLOAT,
temp2 FLOAT )"""
cursor.execute(sql)
#insert to table
try:
cursor.execute("""INSERT INTO temps VALUES (%s,%s)""",(avgtemperatures[0],avgtemperatures[1]))
db.commit()
except:
db.rollback()
#show table
cursor.execute("""SELECT * FROM temps;""")
print cursor.fetchall()
((188L, 90L),)
db.close()
This is the part I need assistance with..
If I have it drop the table it works fine but I don't want it to drop the table, just insert the new data into the same table.
#connect to db
db = MySQLdb.connect("localhost","user","pasword1","temps" )
#setup cursor
cursor = db.cursor()
#create temps table
cursor.execute("DROP TABLE IF EXISTS temps")
sql = """CREATE TABLE temps (
temp1 FLOAT,
temp2 FLOAT )"""
cursor.execute(sql)
#insert to table
try:
cursor.execute("""INSERT INTO temps VALUES (%s,%s)""",(avgtemperatures[0],avgtemperatures[1]))
db.commit()
except:
db.rollback()
#show table
cursor.execute("""SELECT * FROM temps;""")
print cursor.fetchall()
((188L, 90L),)
db.close()
You shouldn`t have to drop a table each time you want to enter data. In fact, it defeats the whole purpose of the database since you will remove all the previous data each time you run your script.
You should ask to create the table but only if it does not exists. Use the following.
sql = """CREATE TABLE IF NOT EXISTS temps (
temp1 FLOAT,
temp2 FLOAT )"""
cursor.execute(sql)
I've had this problem with updating. Try adding COMMIT to the end of your sql. I use psycopg2 to connect to a postgresql database. Here is an example.
def simple_insert():
sql = '''INSERT INTO films VALUES ('UA502', 'Bananas', 105, '1971-07-13', 'Comedy', '82 minutes'); COMMIT;'''
try:
conn = psycopg2.connect(database)
cur = conn.cursor()
cur.execute(sql)
except:
raise
I think your problem is your not saving the transaction and the COMMIT command should fix it.