sqlite value wont update - python-3.x

Im trying to update custommer ("cliente") information in an Sqlite database but there's just one value that wont update. When I tried to update the column 'fechaDeuda' (date of debt) it just wont do it. Weird thing is: I've coded a function to handle all updates and it works fine with all the other cases, even when being called in 'Problematic Line' (see code below) the function executes every statement of the database update and does not throw any exception but still the value in dataBase doesnt change.
Here's the code where I update three values on the same row:
try:
table = 'clientes'
_cliente = sqGenericSelectOne(table, None, 'id', generic.id) # This function retrieves one row based on the arguments passed
clienteID = _cliente[0]
fecha = date_time.split(' - ')[0]
sqUpdateOne(table, 'fechaDeuda', fecha, 'id', clienteID) #### Problematic line (!!!)
nuevoSaldo = float(_cliente[9]) - _pago
if nuevoSaldo < 0:
nuevoSaldo = 0
sqUpdateOne(table, 'saldo', nuevoSaldo, 'id', clienteID) # This line works fine
nuevoTotalPagado = float(_cliente[11]) + _pago
sqUpdateOne(table, 'totalPagado', nuevoTotalPagado, 'id', clienteID) # This one works fine too
except Exception as e:
error(0, e)
**Edit (for some reason this got erased when I posted)**Heres the 'sqUpdateOne' code:
# Sqlite database value updater
def sqUpdateOne(table, column, newValue, refColumn, refValue):
try:
with conn:
c.execute(f'''UPDATE {table} SET {column} = {newValue} WHERE {refColumn} = {refValue}''')
print()
return
except Exception as e:
error(3, e, table)
return
And here's how the dataBase table 'clientes' is created in case it's necessary. The table works fine for everything else. I keep track of it using https://sqliteonline.com/
table = 'clientes'
try:
c.execute(f'''CREATE TABLE {table} (
id integer,
nombre text,
apellido text,
valoracion real,
direccion text,
tel_1 text,
tel_2 text,
correo text,
cantServicios integer,
saldo real,
fechaDeuda text,
totalPagado real,
descripcion text)''')
state(2)
except Exception as e:
error(2, e, table)
Edit: I add here screenshot of sqUpdateOne when called to update 'fecha' so you guys can see the values it gets (again, it works perfectly fine in all other cases):
And heres a screenshot of the dataBase's content before trying to update it (it remains the same after)
Thanks in advance!

I think you are getting an exception when you execute the sqUpdateOne() for the column fechaDeuda because the query string is not quite correct. As it's a text column you need to enclose the value in quotes.
So change how you are setting the variable fecha to wrap it in quotes:
fecha = f'"{date_time.split(' - ')[0]}"'
A sidenote: you could also remove the explicit return statements in sqUpdateOne() as you return from the function any way after these lines.

Related

Inline mode Telegram bot, problem with the request

I am writing a telegram bot with inline mode, everything is fine, but I am faced with such a situation. When I wrote this code:
text = inline_query.query or '0'
the problem is that when I enter data in the chat, it returns to me, first 0, then symbolically and then the total integer value that I entered.
Is it possible to get rid of this so that it outputs the current that I sent in the chat ?
I tried to prescribe a condition but it didn't work out.
For example, I entered 123 and if I write somewhere or just output it, it turns out 0 , 1, 12 ,123.
I want to get the value without unnecessary garbage and so that I can continue to work with it. if something is not clear, I will supplement it
My code:
#dp.inline_handler()
async def inline_money(inline_query: types.InlineQuery) -> None:
text = inline_query.query or '0'
result_id = str(uuid.uuid4().hex)
input_content = InputTextMessageContent(text_all_1)
keyboard = InlineKeyboardMarkup()
button = InlineKeyboardButton('Payment page')
item_2 = InlineQueryResultArticle(
input_message_content=input_content,
id=str(uuid.uuid4().hex),
title='Page',
reply_markup=keyboard.add(button)
)
if text != "0":
cur = conn.cursor()
text_new = float(text)
cur.execute("INSERT INTO payments (indexer, price) VALUES (%s, %s)", (result_id, text_new))
conn.commit()
else:
pass
await bot.answer_inline_query(inline_query_id=inline_query.id, results=[item_2], cache_time=1)

When to use SQL Foreign key using peewee?

I'm currently using PeeWee together with Python and I have managed to create a decent beginner
CREATE TABLE stores (
id SERIAL PRIMARY KEY,
store_name TEXT
);
CREATE TABLE products (
id SERIAL,
store_id INTEGER NOT NULL,
title TEXT,
image TEXT,
url TEXT UNIQUE,
added_date timestamp without time zone NOT NULL DEFAULT NOW(),
PRIMARY KEY(id, store_id)
);
ALTER TABLE products
ADD CONSTRAINT "FK_products_stores" FOREIGN KEY ("store_id")
REFERENCES stores (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE RESTRICT;
which has been converted to peewee by following code:
# ------------------------------------------------------------------------------- #
class Stores(Model):
id = IntegerField(column_name='id')
store_name = TextField(column_name='store_name')
class Meta:
database = postgres_pool
db_table = "stores"
#classmethod
def get_all(cls):
try:
return cls.select(cls.id, cls.store_name).order_by(cls.store)
except Stores.IntegrityError:
return None
# ------------------------------------------------------------------------------- #
class Products(Model):
id = IntegerField(column_name='id')
store_id = TextField(column_name='store_id')
title = TextField(column_name='title')
url = TextField(column_name='url')
image = TextField(column_name='image')
store = ForeignKeyField(Stores, backref='products')
class Meta:
database = postgres_pool
db_table = "products"
#classmethod
def get_all_products(cls, given_id):
try:
return cls.select().where(cls.store_id == given_id)
except Stores.IntegrityError:
return None
#classmethod
def add_product(cls, pageData, store_id):
"""
INSERT
INTO
public.products(store_id, title, image, url)
VALUES((SELECT id FROM stores WHERE store_name = 'footish'), 'Teva Flatform Universal Pride',
'https://www.footish.se/sneakers/teva-flatform-universal-pride-t51116376',
'https://www.footish.se/pub_images/large/teva-flatform-universal-pride-t1116376-p77148.jpg?timestamp=1623417840')
"""
try:
return cls.insert(
store_id=store_id,
title=pageData.title,
url=pageData.url,
image=pageData.image,
).execute()
except Products.DoesNotExist:
return None
except peewee.IntegrityError as err:
print(f"error: {err}")
return None
My idea is that when I start my application, I would have a constant variable which a store_id set already e.g. 1. With that it would make the execution of queries faster as I do not need another select to get the store_id by a store_name. However looking at my code. I have a field that is: store = ForeignKeyField(Stores, backref='products') where I am starting to think what do I need it in my application.
I am aware that I do have a FK from my ALTER query but in my application that I have written I cannot see a reason why I would need to type in the the foreign key at all but I would like some help to understand more why and how I could use the value "store" in my applciation. It could be as I think that I might not need it at all?
Hello! By reading your initial idea about making "the execution of queries faster" from having a constant variable, the first thing that came to mind was the hassle of always having to manually edit the variable. This is poor practice and not something you'd want to do on a professional application. To obtain the value you should use, I suggest running a query programmatically and fetching the id's highest value using SQL's MAX() function.
As for the foreign key, you don't have to use it, but it can be good practice when it matters. In this case, look at your FK constraint: it has an ON DELETE RESTRICT statement, which cancels any delete operation on the parent table if it has data being used as a foreign key in another table. This would require going to the other table, the one with the foreign key, and deleting every row related to the one on the previous table before being able to delete it.
In general, if you have two tables with information linked in any way, I'd highly suggest using keys. It increases organization and, if proper constraints are added, it increases both readability for external users and reduces errors.
When it comes to using the store you mentioned, you might want to have an API return all products related to a single store. Or all products except from a specific one.
I tried to keep things simple due to not being fully confident I understood the question. I hope this was helpful.

How to INSERT into a database using JOIN

I'm currently using PeeWee together with Python and I have managed to create a cool application
CREATE TABLE stores (
id SERIAL PRIMARY KEY,
store_name TEXT
);
CREATE TABLE products (
id SERIAL,
store_id INTEGER NOT NULL,
title TEXT,
image TEXT,
url TEXT UNIQUE,
added_date timestamp without time zone NOT NULL DEFAULT NOW(),
PRIMARY KEY(id, store_id)
);
ALTER TABLE products
ADD CONSTRAINT "FK_products_stores" FOREIGN KEY ("store_id")
REFERENCES stores (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE RESTRICT;
which has been converted to peewee by following code:
# ------------------------------------------------------------------------------- #
class Stores(Model):
id = IntegerField(column_name='id')
store_name = TextField(column_name='store_name')
class Meta:
database = postgres_pool
db_table = "stores"
#classmethod
def get_all(cls):
try:
return cls.select(cls.id, cls.store_name).order_by(cls.store)
except Stores.IntegrityError:
return None
# ------------------------------------------------------------------------------- #
class Products(Model):
id = IntegerField(column_name='id')
title = TextField(column_name='title')
url = TextField(column_name='url')
image = TextField(column_name='image')
store = ForeignKeyField(Stores, backref='products')
class Meta:
database = postgres_pool
db_table = "products"
#classmethod
def add_product(cls, pageData, store_name):
"""
INSERT
INTO
public.products(store_id, title, image, url)
VALUES((SELECT id FROM stores WHERE store_name = 'footish'), 'Teva Flatform Universal Pride',
'https://www.footish.se/sneakers/teva-flatform-universal-pride-t1116376',
'https://www.footish.se/pub_images/large/teva-flatform-universal-pride-t1116376-p77148.jpg?timestamp=1623417840')
"""
try:
return cls.insert(
store_id=cls.select(cls.store.id).join(Stores).where(cls.store.store_name == store_name).get().store.id,
title=pageData.title,
url=pageData.url,
image=pageData.image,
).execute()
except Products.DoesNotExist:
return None
However I have realized that working with id's is quite faster than working with text and I have an issue where I am trying to figure out what would be the best way to insert the ID. I did get a comment regarding my code as for today:
your insert isn't' referencing "stores" at all so not sure what your hoping to get from that since you have a sub query there
I am a bit confused what that means however my question is that I would like to know which approach is the correct way to insert
Is it better on start of application, to store the id as a variable and pass the variable into a insert function (argument)
Or to call store_id=cls.select(cls.store.id).join(Stores).where(cls.store.store_name == store_name).get().store.id where I instead pass the store_name and then it would return the correct id?
My first thought is that by doing the number 2, that is like doing 2 queries instead of one? but I might be wrong. Looking forward to know!
This is quite incorrect:
# Wrong
store_id=cls.select(cls.store.id).join(Stores).where(cls.store.store_name == store_name).get().store.id,
Correct:
try:
store = Stores.select().where(Stores.name == store_name).get()
except Stores.DoesNotExist:
# the store name does not exist. do whatever?
return
Products.insert(store=store, ...rest-of-fields...).execute()

Parameterized SQLite Table Insertion via Python?

I have been trying to get a function working to insert a name in to table of users, but for some reason it just isn't working.
import sqlite3
def CreateUser(Name):
try:
sqliteConnection = sqlite3.connect('Expenses.db')
cursor = sqliteConnection.cursor()
make_user = """INSERT INTO Users (Name) VALUES(?);"""
cursor.execute(make_user, Name)
sqliteConnection.commit()
print()
print('User Successfully Created')
print()
# cursor.close()
except sqlite3.Error as error:
print('Failed to Create User', error)
print()
finally:
if (sqliteConnection):
sqliteConnection.close()
print()
escape = input('Press any key to continue.')
Name = input('> ')
CreateUser(Name)
But for some reason it takes the input string and converts it to the sum of every letter in the string. Inputting a name that is a single digit or letter works, but as soon as it's two or more letters, it throws an error of having too many bindings.
I have tried several variations but I just can't seem to get it working. Can anyone point me in the right direction?
Try binding a tuple containing the name, instead of passing the name variable directly:
sqliteConnection = sqlite3.connect('Expenses.db')
cursor = sqliteConnection.cursor()
make_user = """INSERT INTO Users (Name) VALUES(?);"""
cursor.execute(make_user, (Name,)) # change is here
sqliteConnection.commit()

Cx_Oracle fetch crash

So I've queried data from oracle database using cursor.execute(). A relatively simple select query. It works.
But when I try to fetch data from it, python crashes.
The same occurs for fetchall(), fetchmany() and fetchone().
When the query first broke in fetchmany() I decided to loop through fetchone() and it worked for the first two rows then broke at the third.
I'm guessing it is because there's too much data in third row.
So, is there any way to bypass this issue and pull the data?
(Please ignore the wrong indents could not copy properly in my phone)
EDIT:
I removed four columns with type "ROWID". There was no issue after that. I was easily able to fetch 100 rows in one go.
So to confirm my suspicion I went ahead and created another copy with only those rowed columns and it crashes as expected.
So is there any issue with ROWID type?
Test table for the same.
Insert into TEST_FOR_CX_ORACLE (Z$OEX0_LINES,Z$OEX0_ORDER_INVOICES,Z$OEX0_ORDERS,Z$ITEM_ROWID) values ('ABoeqvAEyAAB0HOAAM','AAAL0DAEzAAClz7AAN','AAAVeuABHAAA4vdAAH','ABoeo+AIVAAE6dKAAQ');
Insert into TEST_FOR_CX_ORACLE (Z$OEX0_LINES,Z$OEX0_ORDER_INVOICES,Z$OEX0_ORDERS,Z$ITEM_ROWID) values ('ABoeqvABQAABKo6AAI','AAAL0DAEzAAClz7AAO','AAAVeuABHAAA4vdAAH','ABoeo+AIVAAE6dKAAQ');
Insert into TEST_FOR_CX_ORACLE (Z$OEX0_LINES,Z$OEX0_ORDER_INVOICES,Z$OEX0_ORDERS,Z$ITEM_ROWID) values ('ABoeqvABQAABKo6AAG','AAAL0DAEzAAClz7AAP','AAAVeuABHAAA4vdAAH','ABoeo+AHIAAN+OIAAM');
Insert into TEST_FOR_CX_ORACLE (Z$OEX0_LINES,Z$OEX0_ORDER_INVOICES,Z$OEX0_ORDERS,Z$ITEM_ROWID) values ('ABoeqvAEyAAB0HOAAK','AAAL0DAEzAACl0EAAC','AAAVeuABHAAA4vdAAH','ABoeo+AHIAAN+OIAAM');
Script:
from cx_Oracle import makedsn,connect,Cursor
from pandas import read_sql_table, DataFrame, Series
from time import time
def create_conn( host_link , port , service_name , user_name , password ):
dsn=makedsn(host_link,port,service_name=service_name)
return connect(user=user_name, password=password, dsn=dsn)
def initiate_connection(conn):
try:
dbconnection = create_conn(*conn)
print('Connected to '+conn[2]+' !')
except Exception as e:
print(e)
dbconnection = None
return dbconnection
def execute_query(query,conn):
dbconnection=initiate_connection(conn)
try:
cursor = dbconnection.cursor()
print ('Cursor Created!')
return cursor.execute(query)
except Exception as e:
print(e)
return None
start_time = time()
query='''SELECT * FROM test_for_cx_oracle'''
try:
cx_read_query = execute_query(query,ecspat_c)
time_after_execute_query = time()
print('Query Executed')
columns = [i[0] for i in cx_read_query.description]
time_after_getting_columns = time()
except Exception as e:
print(e)
print(time_after_execute_query-start_time,time_after_getting_columns-time_after_execute_query)
Unfortunately, this is a bug in the Oracle Client libraries. You will see it if you attempt to fetch the same rowid value multiple times in consecutive rows. If you avoid that situation all is well. You can also set the environment variable ORA_OCI_NO_OPTIMIZED_FETCH to the value 1 before you run the query to avoid the problem.
This has been reported earlier here: https://github.com/oracle/python-cx_Oracle/issues/120

Resources