sqlite3 python3, user input for database - python-3.x

I have been trying to enter direct data to an sqlite database from user input but it only captures the first input and leaves out the rest, where could I be wrong?
Here is the code:
import sqlite3 as lite
class DataInput:
def __init__(self):
self.id = input("Enter ID: ")
self.name = input("Enter name: ")
self.price = input("Enter price: ")
running = True
a = DataInput()
con = lite.connect('kev.db')
with con:
cur = con.cursor()
cur.execute("DROP TABLE IF EXISTS cars")
cur.execute("CREATE TABLE cars(id INT, name TEXT, price INT)")
cur.execute("INSERT INTO cars VALUES(?, ?, ?)", (a.id, a.name, a.price))
while running:
DataInput()
continue

The continue is not helping you.
A constructor that has the side effect of offering three user prompts is, ummm, a bit unusual, but we'll let that one go.
You want to DROP/CREATE once, and then INSERT many times:
with lite.connect('kev.db') as con:
cur = con.cursor()
cur.execute("DROP TABLE IF EXISTS cars")
cur.execute("CREATE TABLE cars(id INT, name TEXT, price INT)")
running = True
while running:
a = DataInput()
cur.execute("INSERT INTO cars VALUES(?, ?, ?)", (a.id, a.name, a.price))

Related

Trying to save a sqlite table inside another table using python

The problem now is that I can only enter one record. No errors are recorded. It just takes the first record from one database and puts in the other database. I am trying to create a machine usable database from the user interface database. I will try to transfer around 100 records once it is working. I would appreciate in comments or suggestions. Thank you!
import sqlite3
sql = 'INSERT INTO heavenStream (scene, cascade, enclosure, sensor, streamer, dither) VALUES (?, ?, ?, ?, ?, ?)'
def dropTable(crs,conn):
crs.execute("DROP TABLE IF EXISTS heavenStream")
def createTable(crs,conn):
sql ='''CREATE TABLE heavenStream(
id INTEGER PRIMARY KEY AUTOINCREMENT,
scene TEXT,
cascade TEXT,
enclosure TEXT,
sensor TEXT,
streamer TEXT,
dither TEXT,
timeStream TEXT,
streamTime TEXT
)'''
crs.execute(sql)
print("Table created successfully........")
def insert_one(conn, crs):
crs.execute("SELECT * FROM animalStream")
for row in crs:
scene = row[1]
cascade = row[2]
enclosure = row[3]
sensor = row[4]
streamer = row[5]
dither = row[6]
print(f"{row[1]} {row[2]} {row[3]} {row[4]} {row[5]} {row[6]}")
try:
crs.execute(sql, (scene, cascade, enclosure,
sensor,streamer,dither))
except sqlite3.IntegrityError as err:
print('sqlite error: ', err.args[0]) # column name is
not unique
conn.commit()
def main():
conn = sqlite3.connect("/home/harry/interface/wildlife.db")
crs = conn.cursor()
dropTable(crs,conn)
createTable(crs,conn)
insert_one(conn, crs)
# conn.commit()
conn.close()
print('done')
main()
The user interface database has had records deleted. There is one record with an id of 64 and the rest are in the 90's.
The cursor (crs) changes here
crs.execute(sql, (scene, cascade, enclosure,sensor,streamer,dither))
after the first insert. Therefore, there are "no more rows to fetch" in the orginal crs.
One solution would be to instantiate another cursor for the insert. Another solution would be to fetchall() the rows into a variable and iterate over that variable as with:
rows = crs.execute("SELECT * FROM animalStream").fetchall()
for row in rows:

Problem with one-to-many relationship sqlite3

I created one-to-many relationship table and according to the sqlite3 documentation I can't insert value into the child table if the referenced table column value in the parent table does not exist.
import sqlite3
class Database:
def __init__(self, database_name):
self.database_name = database_name
def create_table(self, table_name, *columns):
columns = ", ".join(columns)
conn = sqlite3.connect(self.database_name)
cursor = conn.cursor()
_SQL = f"CREATE TABLE IF NOT EXISTS {table_name}({columns})"
cursor.execute(_SQL)
conn.commit()
cursor.close()
conn.close()
def insert_values(self, table_name, values, *columns):
dynamic_values = ('?, ' * len(columns))[0:-2]
columns = ", ".join(columns)
conn = sqlite3.connect(self.database_name)
cursor = conn.cursor()
_SQL = f"INSERT INTO {table_name}({columns}) VALUES ({dynamic_values})"
cursor.execute(_SQL, values)
conn.commit()
cursor.close()
conn.close()
def view_values(self, table_name, *columns):
columns = ", ".join(columns)
conn = sqlite3.connect(self.database_name)
cursor = conn.cursor()
_SQL = f"SELECT {columns} FROM {table_name}"
cursor.execute(_SQL)
the_data = cursor.fetchall()
cursor.close()
conn.close()
return the_data
data = Database("games.db")
#
# data.create_table("supplier_groups", "group_id integer PRIMARY KEY", "group_name text NOT NULL")
#
data.insert_values("supplier_groups", ("Domestic", ), "group_name")
# data.create_table("suppliers ", "supplier_id INTEGER PRIMARY KEY",
# "supplier_name TEXT NOT NULL",
# "group_id INTEGER NOT NULL, "
# "FOREIGN KEY (group_id) REFERENCES supplier_groups (group_id)")
data.insert_values("suppliers", ('ABC Inc.', 9), "supplier_name", "group_id")
as you see on this line: data.insert_values("supplier_groups", ("Domestic", ), "group_name") - I'm inserting a value into supplier_groups table
and then right here: data.insert_values("suppliers", ('ABC Inc.', 9), "supplier_name", "group_id") - I'm inserting value into suppliers table with the group_id that does not exist in the group_suppliers table. Python executes it successfully and adds value to the database, however when attemping to execute this command in SQLITE browser I get this error:
Execution finished with errors. Result: FOREIGN KEY constraint failed which is what python should also have done instead of adding it into the database.
So, could anyone explain me what's going on here? Do I understand something in the wrong way? Help would be appreciated
From Section 2. Enabling Foreign Key Support in the sqlite doc:
Assuming the library is compiled with foreign key constraints enabled, it must still be enabled by the application at runtime, using the PRAGMA foreign_keys command. For example:
sqlite> PRAGMA foreign_keys = ON;

Checking if a user has already voted, returns true even when they haven't?

The user enters their userid and then votes either 'yes' or 'no' but the code returns true and the if statement is executed even when the user hasn't voted.
For example - doing userid = 1 and voting, userid = 1 and voting. The second time userid tries to vote it does say you've already voted but if you then do userid = 2 for the third iteration it says you've already voted, which isn't true.
import sqlite3
conn = sqlite3.connect(":memory:")
cur = conn.cursor()
with conn:
cur.execute("CREATE TABLE users(votes, userid INTEGER)")
for i in range(3):
userid = input("Enter your user id: ")
votes = input("Vote yes or no: ")
with conn:
cur.execute("SELECT * FROM users WHERE votes = 'yes' OR 'no' AND userid = ?", (userid,))
user_voted = cur.fetchall()
if user_voted:
print("You have already voted")
else:
cur.execute("INSERT into users(userid, votes) VALUES(?, ?)", (userid, votes))
print(cur.fetchall())
with conn:
cur.execute("SELECT * FROM users")
print(cur.fetchall())
There are no error messages, it just produces the wrong result
WHERE votes = 'yes' OR 'no'
If you don't want repeated mention of the votes column,
then phrase it as:
WHERE votes in ('yes', 'no')

Convert psycopg2 into asyncpg format. "syntax error at or near "%""

I'm converting a postgres script into asyncpg.
im getting "asyncpg.exceptions.PostgresSyntaxError: syntax error at or near "%""
i assume my placeholder format is incorrect but i cant find an example of a correct format.
Original working psycopg2 code:
async def commit_trade_postgres(response_data_input):
conn = await psycopg2.connect(
"dbname='postgres' user='postgres' password = 'postgres123' host='localhost' port= '5432'")
cur = conn.cursor()
cur.execute(
"CREATE TABLE IF NOT EXISTS trade_{symbol} (time timestamptz NOT NULL ,side text, size float, price float, tick_direction text)".format(**response_data_input))
conn.commit()
cur.execute(
"SELECT create_hypertable('trade_{symbol}', 'time', if_not_exists => TRUE)".format(**response_data_input))
conn.commit()
cur.execute("INSERT INTO trade_{symbol} (time, side, size, price, tick_direction) VALUES (now(), %(side)s, %(size)s, %(price)s, %(tick_direction)s)".format(
**response_data_input), (response_data_input))
conn.commit()
print("commited trade")
My attempt as per the example code supplied int he docs:
async def commit_trade_postgres(response_data_input):
conn = await asyncpg.connect(database='postgres', user='postgres', password='postgres123', host='localhost', port='5432')
await conn.execute(
"CREATE TABLE IF NOT EXISTS trade_{symbol} (time timestamptz NOT NULL ,side text, size float, price float, tick_direction text)".format(**response_data_input))
await conn.execute(
"SELECT create_hypertable('trade_{symbol}', 'time', if_not_exists => TRUE)".format(**response_data_input))
await conn.execute("INSERT INTO trade_{symbol} (time, side, size, price, tick_direction) VALUES (now(), %(side)s, %(size)s, %(price)s, %(tick_direction)s)".format(
**response_data_input), (response_data_input))
print("commited trade")
EDIT: Sample Query, Which i'm extracting 'data' as a dict.
response_dict_instrument = {'topic': 'instrument.BTCUSD', 'data': [{'symbol': 'BTCUSD', 'mark_price': 12367.29, 'index_price': 12360.1}]}
You're formatting query by yourself. You never should do that. Also I would suggest you to create table for every incoming symbol beforehand, do not do this dynamically.
Asyncpg template uses $ sign with number to substitute values to query for you. doc
So, syntax should be like this, if input is dictionary.
async def save_input(input):
# create connection
conn = ...
trade_symbol = input['symbol']
query = "create table if not exists trade_{trade_symbol} ... ".format(trade_symbol=trade_symbol) # your column names go here
await conn.execute(query)
query = "SELECT create_hypertable('trade_{trade_symbol} ...".format(trade_symbol=trade_symbol)
await conn.execute(query)
# i'm not copyng your exact keys, you should do it yourself
values = (input['key1'], input['key2'], input['key3'])
query = "insert into trade_{trade_symbol} (key1, key2, key3) values ($1, $2, $3);".format(trade_symbol=trade_symbol)
await conn.execute(query, *values)
await conn.close()

When i try to insert new value, the old value i inserted earlier gets updated. This is my code

when i inserted the first value and next time when i give different value, the old one gets updated with the new one. I am trying to insert mutiple values and store them without getting them updated. How do i do that?
import pymysql
conn = pymysql.connect(host='127.0.0.1', user='root', passwd='nazaf123', db='nazafdatabase')
cur = conn.cursor()
cur.execute("DROP TABLE IF EXISTS EMPLOYEE")
sql = """CREATE TABLE EMPLOYEE (
FIRST_NAME CHAR(20) NOT NULL,
LAST_NAME CHAR(20),
AGE INT,
SEX CHAR(2),
SALARY FLOAT )"""
cur.execute(sql)
sql = """INSERT INTO EMPLOYEE(FIRST_NAME, LAST_NAME, AGE, SEX, SALARY)
VALUES ('Nazaf', 'Anwar', 22, 'M', 10000)"""
try:
cur.execute(sql)
conn.commit()
except:
conn.rollback()
cur.execute("""SELECT * FROM employee;""")
print(cur.fetchall())
cur.close()
conn.close()
I do not see any code here which does actual updating, unless you can clarify what you are seeing and what you expect to see the following may not help here.
Right now you are deleting a table and recreating it, this will remove all previous data from it. Your Insert statement will typically never alter previous rows for which none exist so I am going to take a guess based on your question that you may have an Update Employee Set (New Data) which would alter the previous record.
To insert new data you will need to perform another Insert command. If you are performing an Update command it will update all records and not insert a new row. Typically Update is followed at the end with a where (Conditional Statement) which lets you limit how the records are modified.
I don't have python or SQL database at this hour this should work. I added onto your provided code however I removed the authentication data.
import pymysql
conn = pymysql.connect({Connection Data here})
cur = conn.cursor()
sql = """INSERT INTO EMPLOYEE(FIRST_NAME, LAST_NAME, AGE, SEX, SALARY) VALUES ('Nazaf', 'Anwar', 22, 'M', 10000)"""
try:
cur.execute(sql)
conn.commit()
except:
conn.rollback()
cur.execute("""SELECT * FROM employee;""")
#You should see the current data here.
sql = """INSERT INTO EMPLOYEE(FIRST_NAME, LAST_NAME, AGE, SEX, SALARY) VALUES ('John', 'Doe', 44, 'M', 300000)"""
cur.execute(sql)
cur.execute("""SELECT * FROM employee;""")
#You should see both Nazaf and John
sql = """UPDATE EMPLOYEE SET SALARY=30 WHERE FIRST_NAME='John'"""
cur.execute(sql)
cur.execute("""SELECT * FROM employee;""")
#You should see both Nazaf and John, however John's salary will be 30
sql = """UPDATE EMPLOYEE SET FIRST_NAME='BOB'"""
cur.execute(sql)
cur.execute("""SELECT * FROM employee;""")
#You should see the first names changed to bob.
print(cur.fetchall())
cur.close()
conn.close()

Resources