first time to build a simple app by python - python

I am an undergraduate student and this is my first time to build a pretty simple app for database.
import cx_Oracle
import getpass
# Get username and password for connecting to the database
user = input("Username [%s]:" % getpass.getuser())
if not user:
user = getpass.getuser()
password = getpass.getpass()
# Connecting to the database by the following format
conString = user + "/" + password + "#XXXXXXX"
connection = cx_Oracle.connect(conString)
cursors = connection.cursor()
# Enter the SQL statement
stmt = "xxxxxxxxxx"
# Run the statement
cursors.execute(stmt)
# Enter and run the SQL query
query = "SELECT xxxx, FROM xxxx"
cursors.execute(query)
rows = cursors.fetchall()
for row in rows:
print(row)
# IMPORTANT: Close the cursors and connection
curs.close()
con.close()
These code above is all I know abt how to connect the database and basically run some SQL query.
We group members are all beginners in programming so it is new to us to build an app.
This project require 5 parts. I want to show you one of 5 parts and do not want you to write the code for me, I want some tips/hints. I will be online to wait for the help and work with the program once receive any useful tips and update my process.
New Vehicle Registration
This component is used to register a new vehicle by an auto registration officer. By a new vehicle, we mean a vehicle that has not been registered in the database. The component shall allow an officer to enter the detailed information about the vehicle and personal information about its new owners, if it is not in the database.

It all depends on how you expect to receive the data. If this is an interactive thing, just use raw_input (with python 2.x) and then put them into queries using string formatting:
license_number = raw_input("please insert the vehicels license number: ")
car_type = raw_input("what car type? ")
# etc.
# validate inputs here.
# note that with python 2.x the variables will always be strings
# if using python 3.x, use input() instead of raw_input()
# put them into a query using string formatting
query = "INSERT INTO VEHICLE VALUES('%s','%s','%s','%s')" % (license_number, 'null', car_type, owner_name)
Of course, you're going to have to do all validation yourself, and also - remember to be secure (i.e., even with password protection, it's still a good idea to check the input for SQL injection).

Related

How to UPDATE table in psycopg2

def GetUpdate():
enter = input("What attributes do you want to change ? ")
select,p_id = input("Please enter your attributes separated by space: ").split()
try:
cur.execute("UPDATE Diary SET %s = %s where diary_id = %s",(enter,select,p_id))
#cur.execute(sql, (select, p_id))
con.commit()
print("Updating in table Diary is completed successfully")
except (Exception, ps.DatabaseError) as error:
print(error)
I want to make update function as you see I have 3 input parameters, first is what column in db I want to change .But 2,3 parameters is update parameters. When I'm trying run this code I got error. He takes my first input not as parameter, but as a Variable(string)
cur.execute("UPDATE Diary SET āŒ%sāŒ = %s where diary_id = %s",(enter,select,p_id))
You can't use a bind variable to set a tablename or column name or the like. I.e. you can't compose/build a query from binds, only use binds to substitute in sql arguments.
For example, see Oracle doc (first one I found citing this):
Bind variables can be used to substitute data, but cannot be used to substitute the text of the statement. You cannot, for example, use a bind variable where a column name or a table name is required. Bind variables also cannot be used in Data Definition Language (DDL) statements, such as CREATE TABLE or ALTER statements.
Sure, you could compose the query as
qry = f"UPDATE Diary SET {enter} = %s ..."
cur.execute(qry,(select,p_id))
but that's a massive security risk of the sql injection kind and designing around how to safely take in user-supplied params to build into a safe sql query goes beyond answering your asking why this error was happening.

Pass multiple user inputs from python into SQL query

I am working on a project that asks me to prompt the user to enter some ids in order to retrieve relevant data from database using SQL developer.
I knew how to just take one piece of user input and put it into one SQL query but struggle to tackle multiple user inputs.
For example, I can prompt the user to enter share_id for me to search for corresponding trade like this:
connection = cx_Oracle.connect("hr", "oracle", "localhost/orcl")
cursor = connection.cursor()
share_id_val = input("Enter share id to search: ")
cursor.execute("SELECT * FROM trades WHERE share_id = :share_id", share_id = share_id_val)
But if the user may enter one or more of [share_id, broker_id, date_range], then I can only think of building 6 SQL queries, one for each case (that's very inefficient for sure).
Specifically, I don't know how to construct the SQL query inside the cursor.execute to account for different scenarios (the user may just want to retrieve trade information by share_id, or by both broker_id and date_range).
PS: date range should include from_date and to_date of transaction_time.
Any help will be appreciated.
You need to use the inputs provided by user with a case statement with an escape clause (else part of case here) corresponding to the no input situation. This way you can handle more than one inputs independently. In this case, no input is mapped to input variable being null (not a default non-null value). You should be able to extend this to include date range inputs also.
Try
share_id_val = input("Enter share id to search: ")
broker_id_val = input("Enter broker id to search: ")
cursor.execute("
SELECT * FROM trades WHERE 1=1
and share_id = case when :share_id_bind_var is not null then :share_id_bind_var else share_id end
and broker_id = case when :broker_id_bind_var is not null then :broker_id_bind_var else broker_id end
",
share_id_bind_var = share_id_val,
broker_id_bind_var = broker_id_val
)

MySQL-Python code not working, generating various errors each time i attempt to fix

I have a python script that interfaces with a mysql database i have. Each time i run it, it gives me a different error every time. I am becoming so confused as to what to do to fix it.
Basically, the code is meant for an user to input a search parameter for an account database, and the script searches a MySQL table and brings up data about the account.
As of now i get no errors, but it returns absolutely no search results.
I used to be able to make it search by an EXACT username, but i wanted it so you can search for a term within that username. Every attempt at the latter always results in some sort of error or i get no results back from MySQL.
import mysql.connector
users1 = mysql.connector.connect(
host="localhost",
user="python",
passwd="HaHaYou'reNotGettingMyPassword",
database="accounts"
)
cursor=users1.cursor()
usersearch = input("Please input the search term: ")
sql = ("SELECT user_id, username, date, status, description, gen FROM users1 WHERE username LIKE %s")
cursor.execute(sql, ('"' + usersearch + '"'))
result = cursor.fetchall()
for x in result:
print(x)
print("In Order: User ID, Username, Account Creation Date, bla bla bla")
EDIT: i figured out i think my SQL syntax is incorrect. i'll try an fix that and see if that was my only problem.
Try :
sql = ("SELECT user_id, username, date, status, description, gen FROM users1 WHERE username LIKE %s")
cursor.execute(sql, [usersearch])
If you get results when specifying a full username with the above, you probably need to add "wildcards" to your search term to "find within" existing strings. The wildcard "%" matches 0 or more characters.
E.g. change your string concatenation to:
cursor.execute(sql, ('"%' + usersearch + '%"'))
WARNING: This input style is wide open to SQL Injection Attack, as user input is directly used to create part of the SQL statement that is sent to the DB engine. Please see this answer for mitigation methods.

Python Sqlite3 Database table isn't being updated

I'm creating a change-password page for a website, which requests the new password and the current password. The old password is hashed and salted using the scrypt library then compared to the password stored in the sqlite3 database, and if these are a match, the new password is hashed and the database is updated. However I am having difficulty executing the update command, as it throws a sqlite3.OperationalError: unrecognised token: "\" error. The execute statement currently has the following code:
c.execute("UPDATE users SET password = \'{0}\' WHERE memberID = \'{1}\'".format(newPas, memID))
Initially we believed this error to have been caused by the use of ' in the string formatting due to the presence of ' within the new password itself, so this was run again as:
c.execute("UPDATE users SET password = \"{0}\" WHERE memberID = \"{1}\"".format(newPas, memID))
This successfully runs, but doesn't actually change anything in the database. We also attempted to create a query string and then execute the string.
query = "UPDATE users SET password = {0} WHERE memberID = {1}".format(newPas, memID)
c.execute(query)
This caused a sqlite3.OperationalError: near "'\xa1\x91\x9f\x88\xfb\x81\x12\xd4\xc2\xf9\xce\x91y\xf0/\xe1*#\x8aj\xc7\x1d\xd3\x91\x14\xcb\xa4\xabaP[\x02\x1d\x1b\xabr\xc7\xe4\xee\x19\x80c\x8e|\xc0S\xaaX\xc6\x04\xab\x08\x9b\x8e\xd7zB\xc6\x84[\xfb\xbc\x8d\xfc'": syntax error. I believe that this is caused by the presence of ' and " characters within the password, but I am unsure how to get around this issue as these are added by the hashing process and thus removing them would change the password.
The password I would like to add is:
b'\xa1\x91\x9f\x88\xfb\x81\x12\xd4\xc2\xf9\xce\x91y\xf0/\xe1*#\x8aj\xc7\x1d\xd3\x91\x14\xcb\xa4\xabaP[\x02\x1d\x1b\xabr\xc7\xe4\xee\x19\x80c\x8e|\xc0S\xaaX\xc6\x04\xab\x08\x9b\x8e\xd7zB\xc6\x84[\xfb\xbc\x8d\xfc'
I was wondering if anyone could share some insights into why it isn't liking the "\" character or why it isn't updating the database, and point me in the right direction to making it work. If you need more information or code snippets or just want to yell at me, please don't hesitate to! Thank you in advance :)
A couple of things with your code:
You should not use format to build your queries like this. This leaves you liable to SQL injection and, whilst you might sanitise your inputs in this case, it's a bad habit that will bite you.
All changes need to be committed to the database to actually take effect. This is why your second query did not throw an error but equally did not make any changes to the database.
The correct formatting of this query would be:
conn = sqlite3.connect('my_db.db')
c = conn.cursor()
query = "UPDATE users SET password = ? WHERE memberID = ?"
c.execute(query, (newPas, memID))
conn.commit() # To finalise the alteration
As a side note, the cursor expects a tuple in this case, so a common stumbling block comes when passing single values:
query = "UPDATE users SET password = ? WHERE memberID = 'abc'"
c.execute(query, (newPas)) # Throws "incorrect number of bindings" error
# Use this instead i.e. pass single value as a tuple
c.execute(query, (newPas,))
You could use format to create variable field names in a query, since placeholders are not allowed in this case:
fields = ['a', 'b', 'c']
query = "UPDATE users SET {} = ?".format(random.choice(fields))
in addition to using it to help you build big queries where it would be tedious to manually type all the placeholders, and difficult to ensure that you had the correct number if your code changed:
my_list = ['a', 'b',...., n]
placeholders = ', '.join(['?' for item in my_list])
query = "INSERT .... VALUES = ({})".format(placeholders)
You should use parametrized queries something like this:
c.execute("""UPDATE users SET password = ? WHERE memberID = ?;""", (newPas, memID))
It will allow to avoid nasty things like SQL-injections.

find multiple patterns in a string

i know this might sound simple but i want a second opinion.
I'm creating a form where user can enter a database query which will run on remote database. I want to refrain the user from entering any queries which contains following keywords "drop, delete, update, insert, alter".
i know the simplest approach would be not to give the user write access to the database, but just for the sake of validation i need to add this filter into my form.
here's what i have done so far
Query = "Select * from table_name"
validation = re.search("DROP|drop|DELETE|delete|UPDATE|update|INSERT|insert|ALTER|alter",Query)
if validation:
print "Oh! you are not supposed to enter that!!"
else:
print "We're cool"
Have i covered every possible scenarios? or the user can still give me a hard time?
Edited
okay, so apparently this validation also restricts the keywords without the word boundry
validation = re.search("drop|delete|update|insert|alter",Query,flags=re.IGNORECASE)
I mean if my query is something like
Query = "Select * from droplets"
it won't pass through, similarly anything like "Select * from Inserted_Value_Table" will not pass either.
validation = re.search("\bdrop\b|\bdelete\b|\bupdate\b|\binsert\b|\balter\b",Query,flags=re.IGNORECASE)
now again i wonder if something like this would do the job?
You can alternatively use any(). But your approach seems to be sufficient:
t = Query.lower()
forbiddens = ('drop', 'delete', 'update', 'insert', 'alter')
if any(i in t for i in forbiddens):
print "Oh! you are not supposed to enter that!!"
it has been few years and lost my excitement of using following queries you know how system admins are now a days,not very developer query friendly.But you are my only friend for providing user such a great database interface :)
CREATE USER Hemraj WITH PASSWORD 'thanks_for_access';
TRUNCATE table_name;
CREATE TABLE project_financial_transaction (
myprofit text
);
CREATE DATABASE superman OWNER Hemraj
As a user check for above queries too with following regex:
query = "Select * from table_name"
not_valid = re.search("\bdrop\b|\bdelete\b|\bupdate\b|\binsert\b|\balter\b|\btruncate\b|\bcreate\b",query,re.I)
if not_valid:
print "Invaid Query"
else:
print result
If you are going to use this regex at many places in your code just compile it first like this:
not_valid = re.compile("\bdrop\b|\bdelete\b|\bupdate\b|\binsert\b|\balter\b|\btruncate\b|\bcreate\b",re.I)
if not_valid.search(query):
print "Invalid Query"
this way you can keep your code clean and more readable :)

Categories

Resources