How to express a python variable in a SQLITE3 statement - python

I have created the following functions to create a table call user.
import sqlite3
from datetime import datetime
def create_connection(db_file):
try:
connection = sqlite3.connect(db_file)
return connection
except sqlite3.Error as e:
print(e)
return None
def create_table(connection, sql_table):
cursor = connection.cursor()
with connection:
try:
cursor.execute(sql_table)
except sqlite3.Error as e:
print(e)
def insert_user(connection, date, username):
cursor = connection.cursor()
with connection:
cursor.execute("INSERT INTO user VALUES(?,?)",(date, username))
database = "test.db"
user_table = """ CREATE TABLE IF NOT EXISTS user (
date TEXT NOT NULL,
username TEXT NOT NULL
); """
conn = create_connection(database)
create_table(conn, user_table)
date = datetime.now().strftime('%Y-%m-%d')
username = 'user1'
insert_user(conn, date, username)
I would like to make the function insert_user more general. I would like to be able to pass user into this function and not have to explicitly write user in
cursor.execute("INSERT INTO user VALUES(?,?)",(date, username))
Similarly, I would like to avoid explicitly writing user in
user_table = """ CREATE TABLE IF NOT EXISTS user (
Rather I would like to have a variable having the value of user and passing that variable into this statement.
How should I amend my code? Thanks.

Related

same thread error or sqlite3.OperationalError: no such column: None

I want to add a new value into the field stock_type where user_id = 1
How i created the database in login.py:
import sqlite3
conn = sqlite3.connect("users.db")
cur = conn.cursor()
try:
cur.execute("""
CREATE TABLE users(
"user_id" integer,
"username" text,
"password" text,
"home" text,
"work" text,
"trans_meth" text,
"stock_type" text,
"inter_loc" text,
"reminders_str" text,
"news_prov" text,
"time_to_work" integer,
"stocks" integer,
"time" integer,
"reminders" integer,
"weather" integer,
"news" integer
)""")
cur.execute("""
INSERT INTO users(user_id)
VALUES(1)""")
conn.commit()
conn.close()
except:
print("table already exists")
code in register.py causing the issue:
import sqlite3
conn = sqlite3.connect("users.db")
cur = conn.cursor()
def update(stock, enter):
if enter > 0:
cur.execute(f"""
UPDATE users
SET stock_type = {stock}
WHERE user_id = 1;
""")
conn.commit()
conn.close()
return ""
at first i got an error
cur.execute(f"""
sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 139888482103936 and this is thread id 139888351504128.
to fix this i added check_same_thread to sqlite3.connect() and set it to False
conn = sqlite3.connect("users.db", check_same_thread=False)
this fixed this issue however now
I got a new error
File "/workspaces/programming project/pages/register.py", line 93, in update
cur.execute(f"""
sqlite3.OperationalError: no such column: None
i have tried adding conn.commit() and conn.close() however neither of these have helped.
i have also tried adding:
conn = sqlite3.connect("users.db", check_same_thread=False) and
cur = conn.cursor()
into the update function however this also hasn't helped

I'm trying to insert data that I've scrapped off twitter into my postgres database but failing

I'm using snscrape lib to scrape twitter data off twitter. I want to insert this data into my database but I seem to be failing no matter what method I try. when I use a loop and create a sql query after the loop to insert the values 1 by 1. I get an IndexError and a TypeError. When I try to append the data into a list. I can't loop in to each value 1 by 1. Now I'm stuck and don't know what to do.
method 1
class Tweet_list():
def tweets_list1(self):
dbname = '******'
user = '******'
password = '******'
host = '*******'
port = ****
cur = None
conn = None
try:
conn = psycopg2.connect(
dbname = dbname,
user = user,
password = password,
host = host,
port = port
)
cur = conn.cursor()
cur.execute('DROP TABLE IF EXISTS Machine_twitter')
create_table = '''CREATE TABLE IF NOT EXISTS Machine_twitter (
id int PRIMARY KEY,
Tweet text,
Tweet_id int,
Timestamp timestamp,
Replys int,
Retweets int,
Likes int,
Username char)'''
cur.execute(create_table)
for i, tweet in enumerate(sntwitter.TwitterSearchScraper('from:TheHoopCentral').get_items()):
if i > 5:
break
insert_tweet = 'INSERT INTO Machine_twitter (Tweet, Tweet_id, Timestamp, Replys, Retweets, Likes, Username) VALUES (%s, %s, %s, %s,%s, %s, %s)'
insert_values = (tweet.content, tweet.id, tweet.date, tweet.replyCount, tweet.retweetCount, tweet.likeCount, tweet.user.username)
cur.execute(insert_tweet, insert_values)
conn.commit()
print('completed')
except Exception as error:
print(error)
finally:
if cur is not None:
cur.close()
if conn is not None:
conn.close()
tweets = Tweet_list()
tweets2 = Tweet_list()
tweets2.tweets_list1()
error
IndexError: list index out of range
method 2
def update_list1(self):
tweets_list2 = []
for i, tweet in enumerate(sntwitter.TwitterSearchScraper('from:TheHoopCentral').get_items()):
if i > 100:
break
tweets_list2.append([tweet.content, tweet.id,tweet.likeCount, tweet.retweetCount, tweet.replyCount, tweet.user.username])
tweet_df = pd.DataFrame(tweets_list2, columns=('tweet', 'tweet id', 'likeCount', 'retweetCount', 'replyCount', 'username'))
tweet_df.head()
the problem with the second method is that after the list gets appended. I can't access the values(eg. tweet.content) so I can insert them into the database. I've tried every method under the sun but I'm failing miserably can somebody help.

Python SQLite3 issue searching table

I have a Python function that is supposed to check if a value is present in my SQLite table. I have a table named Users and it stores the value userid which is a random string of integers and letters. For example, a userid would look like this f75fsf3dbg9g. In def chk(): the user inputs their uid then the uid_chk(): function is called to check if the uid value equals one of the userid being stored in the table.
My issue is in the cur.execute(query,tagValue) line in the uid_chk() function. It throws the Error: sqlite3.programmingError: Incorrect number of bindings supplied. The current statement uses 1
Nothing is being returned from the function uid_chk() just prints out None
For reference when the table Users is printed out it looks like this: [('hk12lkj14vh',),('bn465i32',),('d8j4k0fl',),('k4i9b3k0s2',),('rk2nk50sp26',),('rk3ji9al23',),]
import RPi.GPIO as GPIO
import sqlite3 as sql
from mfrc522 import SimpleMFRC522
reader = SimpleMFRC522()
def chk():
print("Scan tag")
try:
uid_tag = reader.read()
#If the user has inputed value (uid)
if uid_tag :
#Var for inputed userid
tagValue = uid_tag[1]
print(tagValue)
uid_chk(tagValue)
return tagValue
GPIO.cleanup()
except ValueError:
print('Something went wrong')
def uid_chk(tagValue):
Database = sql.connect('test.db')
# cursor
cur = Database.cursor()
# Check if the tagValue maches a value in the userid column of sqlite DB
query = 'SELECT userid FROM Users WHERE userid = ?'
cur.execute(query, tagValue)
row_returned = cur.fetchone()
print(row_returned)
if row_returned == tagValue:
print('User Verified')
else:
print('Something is Wrong')
Database.close()
chk()

How to fix {"message": "The method is not allowed for the requested URL." } for my post method?

This is the first time I'm creating an API for android retrofit. I modified this code according to the snippet I got online. The main functionality of the post method is to take the given parameters and store it in the sqlite3 database.
My schema of the following two tables:
sqlite> .schema spending
CREATE TABLE spending(
ID INTEGER PRIMARY KEY AUTOINCREMENT,
date TEXT ,
reason TEXT ,
amount INTEGER
);
CREATE TABLE receiving(
ID INTEGER PRIMARY KEY AUTOINCREMENT,
date TEXT ,
from_reason TEXT ,
amount INTEGER
);
from flask import Flask, request
from flask_restful import Resource, Api
from sqlalchemy import create_engine
from flask import jsonify
db_connect = create_engine('sqlite:///api.db')
app = Flask(__name__)
api = Api(app)
class AddSpending(Resource):
def add_spending(self):
try:
_json = request.json
_date = _json['date']
_reason = _json['reason']
_amount = _json['amount']
# validate the received values
if _date and _reason and _amount and request.method == 'POST':
#do not save password as a plain text
#_hashed_password = generate_password_hash(_password)
# save edits
sql = "INSERT INTO spending(date, reason, amount) VALUES(%s, %s, %d)"
data = (_date, _reason, _amount)
#conn = mysql.connect()
conn = db_connect.connect()
cursor = db_connect.cursor()
conn.cursor()
conn.execute(sql, data)
conn.commit()
#resp = jsonify('Spending added successfully!')
#resp.status_code = 200
return
else:
return 404
except Exception as e:
print(e)
finally:
cursor.close()
conn.close()
api.add_resource(AddSpending, '/spending_up',methods=['POST']) # Route_3
When a user passes data through this parameter. The data should be stored in the database
I think the problem is that you called you method as add_spending and shoud be named as post
change def add_spending(self) by def post(self)
the code for your api should look like that, without the methods='POST'
class AddSpending(Resource):
def post(self):
try:
_json = request.json
_date = _json['date']
_reason = _json['reason']
_amount = _json['amount']
# validate the received values
if _date and _reason and _amount and request.method == 'POST':
#do not save password as a plain text
#_hashed_password = generate_password_hash(_password)
# save edits
sql = "INSERT INTO spending(date, reason, amount) VALUES(%s, %s, %d)"
data = (_date, _reason, _amount)
#conn = mysql.connect()
conn = db_connect.connect()
cursor = db_connect.cursor()
conn.cursor()
conn.execute(sql, data)
conn.commit()
#resp = jsonify('Spending added successfully!')
#resp.status_code = 200
return
else:
return 404
except Exception as e:
print(e)
finally:
cursor.close()
conn.close()
api.add_resource(AddSpending, '/spending_up') # Route_3
UPDATE
I just tried with a code similar to yours and worked
ANOTHER UPDATE
your repo code

Database is locking but all statements are followed by commit?

I'm working on an IRC bot, forked from a modular bot called Skybot.
There are two other modules that make use of the sqlite3 database by default; they have both been removed and their tables dropped, so I know that the issue is somewhere in what I'm doing.
I only call 3 db.execute() statements in the whole thing and they're all immediately committed. This thing isn't getting hammered with queries either, but the lock remains.
Relevant code:
def db_init(db):
db.execute("create table if not exists searches"
"(search_string UNIQUE PRIMARY KEY,link)")
db.commit()
return db
def get_link(db, inp):
row = db.execute("select link from searches where"
" search_string=lower(?) limit 1",
(inp.lower(),)).fetchone()
db.commit()
return row
def store_link(db, stub, search):
db.execute("insert into searches (search_string, link) VALUES (?, ?)", (search.lower(), stub))
db.commit()
return stub
If the script only has to touch db_init() and get_link() it breezes through, but if it needs to call store_link() while the database is unlocked it will do the insert, but doesn't seem to be committing it in a way that future calls to get_link() can read it until the bot restarts.
The bot's db.py:
import os
import sqlite3
def get_db_connection(conn, name=''):
"returns an sqlite3 connection to a persistent database"
if not name:
name = '%s.%s.db' % (conn.nick, conn.server)
filename = os.path.join(bot.persist_dir, name)
return sqlite3.connect(filename, isolation_level=None)
bot.get_db_connection = get_db_connection
I did adjust the isolation_level myself, that was originally timeout=10. I am fairly stumped.
EDIT: The usages of get_db_connection():
main.py (main loop):
def run(func, input):
args = func._args
if 'inp' not in input:
input.inp = input.paraml
if args:
if 'db' in args and 'db' not in input:
input.db = get_db_connection(input.conn)
if 'input' in args:
input.input = input
if 0 in args:
out = func(input.inp, **input)
else:
kw = dict((key, input[key]) for key in args if key in input)
out = func(input.inp, **kw)
else:
out = func(input.inp)
if out is not None:
input.reply(unicode(out))
...
def start(self):
uses_db = 'db' in self.func._args
db_conns = {}
while True:
input = self.input_queue.get()
if input == StopIteration:
break
if uses_db:
db = db_conns.get(input.conn)
if db is None:
db = bot.get_db_connection(input.conn)
db_conns[input.conn] = db
input.db = db
try:
run(self.func, input)
except:
traceback.print_exc()
Send conn in your functions, along with db, as mentioned. If you wrote the code yourself, you'll know where the database actually is. Conventionally you would do something like:
db = sqlite3.connect('database.db')
conn = db.cursor()
Then for general usage:
db.execute("...")
conn.commit()
Hence, in your case:
def db_init(conn,db):
db.execute("create table if not exists searches"
"(search_string UNIQUE PRIMARY KEY,link)")
conn.commit()
return db
def get_link(conn,db, inp):
row = db.execute("select link from searches where"
" search_string=lower(?) limit 1",
(inp.lower(),)).fetchone()
conn.commit()
return row
def store_link(conn,db, stub, search):
db.execute("insert into searches (search_string, link) VALUES (?, ?)", (search.lower(), stub))
conn.commit()
return stub
On the basis that you have set the isolation_level to automatic updates:
sqlite3.connect(filename, isolation_level=None)
There is no need whatsoever for the commit statements in your code
Edit:
Wrap your execute statements in try statements, so that you at least have a chance of finding out what is going on i.e.
import sqlite3
def get_db(name=""):
if not name:
name = "db1.db"
return sqlite3.connect(name, isolation_level=None)
connection = get_db()
cur = connection.cursor()
try:
cur.execute("create table if not exists searches"
"(search_string UNIQUE PRIMARY KEY,link)")
except sqlite3.Error as e:
print 'Searches create Error '+str(e)
try:
cur.execute("insert into searches (search_string, link) VALUES (?, ?)", ("my search", "other"))
except sqlite3.Error as e:
print 'Searches insert Error '+str(e)
cur.execute("select link from searches where search_string=? limit 1", ["my search"])
s_data = cur.fetchone()
print 'Result:', s_data

Categories