sqlite3 python adding columns and updating values - python

I am learning how to use sqlite3 in python. I have a simple table with 2 columns: ID and name.
I tried adding a new column to this table using the following commands (I am working in ipython):
conn = sqlite3.connect('mydatabase.db')
c = conn.cursor()
c.execute("alter table studentinfo add column Group integer")
I get the following error:
OperationalError: near "Group": syntax error
Then, based on the examples here on S.O. I tried,
c.execute("alter table studentinfo add column 'Group' integer")
This worked. However, I have another problem now. Apparently the column name is "'Group'" instead of just "Group".
For example, when I try to update the value in this column, of the following three commands, one works and two do not.
conn = sqlite3.connect('mydatabase.db')
c = conn.cursor()
c.execute("update studentinfo set Group=1 where ID <= 4") #This did not work.
I get the following error:
OperationalError: near "Group": syntax error
Then I tried to put quotes around column names:
c.execute("update studentinfo set 'Group'=1 where 'ID' <= 4")
#This did not work either. Gives no error, but does not do anything. Records remain
#unchanged.
Then, I tried with quotes around Group but not around ID. This worked fine.
c.execute("update studentinfo set 'Group'=1 where ID <= 4") #This worked fine.
That is, it thinks of the column name as 'Group' (with the quotes). How do I add a column with just the name Group?
Thank you.

When table name or column name is the same as SQL keywords (such as GROUP), errors are generated. You need to quote the table name with ` `, not ' '. So you could use:
alter table studentinfo add column `Group` integer

GROUP is an SQLite keyword.
Resolution: Name your column something else.

The trouble is how you performed the ALTER TABLE command. By including single quotes around the column name you specified that was part of the name. Drop the quotes, and it should work as you expect.
FYI: you can query the schema in sqlite3 with the dot-s command (.s). It will show you the true column names. Here's a quick sample:
SQLite version 3.7.9 2011-11-01 00:52:41
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> create table a( mycol1 INT );
sqlite> alter table a add column mycol2 int;
sqlite> alter table a add column 'mycol3' int;
sqlite> .s
CREATE TABLE a( mycol1 INT , mycol2 int, 'mycol3' int);
sqlite>

Related

Select Query: Error Code 1292 - Truncated incorrect DOUBLE value

I'm attempting to retrieve all the data from a column in mysql by having the user input which table and column the data is through the mysqlconnector library in python. When I ran the query through python no data would show up and then when I ran it through Phpmyadmin I would get these errors:
Warning: #1292 Truncated incorrect DOUBLE value: 'Matisse'
Warning: #1292 Truncated incorrect DOUBLE value: 'Picasso'
Warning: #1292 Truncated incorrect DOUBLE value: 'van Gogh'
Warning: #1292 Truncated incorrect DOUBLE value: 'Deli'
I found the query only works for columns that are integer based and does not work for date-time or varchar columns (The L_Name one from which the query doesn't work is varchar(25).
Here is the query:
SELECT * FROM `artist` WHERE L_Name
After the query is run and throws those errors, the query changes to this by itself:
SELECT * FROM `artist` WHERE 1
This new query returns the whole table and all of its columns and rows but of course all I want is for it to simply return the single column.
EDIT: To clarify, the point of running the SELECT * FROM `artist` WHERE L_Name
query is to bring up the whole list of values in that column for that table. This is just one case and there's many other cases like if the user wanted to search up a specific record from the art_show table and then look at all the values in the column of the gallery location.
I don't think its the error thats the problem since you did varchar, maybe check your python code?
Figured out the solution. My Python had an issue where it would only print the first value due to how I set up the print statement. Fixed it by changing the query on the 3rd line and also changing the print statement from print(rec[0]) to print(rec)
def show_entries(table, column):
print(f"Here's the records in the table {table} and the column {column}.")
mycursor.execute(f"SELECT {column} FROM {table}")
myresult = mycursor.fetchall()
for rec in myresult:
print(rec)

Is there a function which will take schema name and table name and return all the column names in the table

I am trying to use python to download a table from oracle database using CX_Oracle module
This below command is executed in a notebook along with the credential
temp = list()
for row in c.execute('SELECT * FROM dbname.tablename'):
temp.append(row)
df = pd.DataFrame(temp)
I am able to get all the rows into the variable temp but. I also would like to get the column names as well.
So my approach was to get the column name separately and add them to the above df.
For a given schema name and a table name, I want to find the column names of that table in Oracle.
"This doesn't return anything so far but the column exsist '
select table_name
from all_tab_columns
where column_name = 'modby'
Thanks in advance for your assistance
By default, Oracle stores object and column names in uppercase, so try
select table_name
from all_tab_columns
where column_name = 'MODBY' --> instead of 'modby'
You need to use upper or lower on both sides of comparison as Oracle DB behave case-sensitivity differently. object names (table, column, etc) are stored case-sensitively if they are wrapped in " while creating else oracle DB converts all the object names without double quotes into the uppercase name.
Try the following query:
select table_name
from user_tab_columns
where lower(column_name) = 'modby'
If you want all column names of the table then try the following query:
select column_name
from user_tab_columns
where lower(table_name) = lower('<your_table_name>');
Cheers!!

Python pyodbc is not recognizing parameter marker. I've supplied 2 markers and two values but its not recognizing them

Any idea why the code below would not recognize the first placeholder? I'm assuming I have to put a special character in front of it but i've been unable to find any documentation around it. I've also tried just a simple "create table ?" with no success.
for champ in champion_list:
UPDATE_SQL = """\
if not exists (select * from sysobjects where name=? and xtype='U')
CREATE TABLE [dbo].[?](
[champId] [varchar](50) NOT NULL,
[championName] [varchar] NOT NULL,
[version] [varchar](50) NOT NULL
) ON [PRIMARY]
"""
values=(champ,champ)
try:
cursorprod.execute(UPDATE_SQL, values)
print str(champ),'table added.'
except Exception as e:
print(e)
I get the error
The SQL contains 1 parameter markers, but 2 parameters were supplied
Query parameters are for specifying column values in DML statements; they cannot be used to specify object (e.g., column or table) names in DDL statements. You will need to use dynamic SQL (string substitution) for that ...
... assuming that you really want to create separate tables for each item in the list. If the structure of those tables is identical then that is a bad design. You'd be better served with one table that includes an extra column to identify the list item associated with each row.

sqlite3 in Python: Update a column in one table through a column from another table when the primary key is the same

I want to use sqlite3 in Python. I have a table with four columns (id INT, other_no INT, position TEXT, classification TEXT, PRIMARY KEY is id). In this table, the column for classification is left empty and will be updated by the information from table 2. See my code below. I then have a second table which has three columns. (id INT, class TEXT, type TEXT, PRIMARY KEY (id)). Basically, the two tables have two common columns. In both tables, the primary key is the id column, the classification and class column would eventually have to be merged. So the code needs to be able to go through table 2 and whenever it finds a matching id in table 1 to updating the class column (of table 1) from the classification column of table 2. The information to build the two tables comes from two separate files.
# function to create Table1...
# function to create Table2...
(the tables are created as expected). The problem occurs when I try to update table1 with information from table2.
def update_table1():
con = sqlite3.connect('table1.db', 'table2.db') #I know this is wrong but if how do I connect table2 so that I don't get error that the Table2 global names is not defined?
cur = con.cursor()
if id in Table2 == id in Table1:
new_classification = Table2.class # so now instead of Null it should have the class information from table2
cur.execute("UPDATE Table1 SET class = ? WHERE id =? ", (new_classification, id))
con.commit()
But, I get an error for line2: TypeError: a float is required. I know that it's because I put two parameters in the connect method. But then if I only connect with Table1 I get the error Table2 is not defined.
I read this post Updating a column in one table through a column in another table I understand the logic around it but I can't translate the SQL code into Python. I have been working on this for some time and can't seem to just get it. Would you please help? Thanks
After the comments of a user I got this code but it still doesn't work:
#connect to the database containing the two tables
cur.execute("SELECT id FROM Table1")
for row in cur.fetchall():
row_table1 = row[0]
cur.execute("SELECT (id, class) FROM Table2")
for row1 in cur.fetchall():
row_table2 = row[0] #catches the id
row_table2_class = row[1] #catches the name
if row_table1 == row_table2:
print "yes" #as a test for me to see the loop worked
new_class = row_table_class
cur.execute("UPDATE Table1 SET classification=? WHERE id=?", (new_class, row_table1))
con.commit()
From this however I get an operational error. I know it's my syntax, but like I said I am new to this so any guidance is greatly appreciated.
You need a lot more code than what you have there. Your code logic should go something like this:
connect to sqlite db
execute a SELECT query on TABLE2 and fetch rows. Call this rows2.
execute a SELECT query on TABLE1 and fetch rows. Call this rows1.
For every id in rows1, if this id exists in rows2, execute an UPDATE on that particular id in TABLE1.
You are missing SELECT queries in your code:
cur = con.cursor()
if id in Table2 == id in Table1:
new_classification = Table2.class
You can't just directly test like this. You need to first fetch the rows in both tables using SELECT queries before you can test them out the way you want.
Find below modified code from what you posted above. I have just typed that code in here directly, so I have not had the chance to test it, but you can look at it to get an idea. This could probably even run.
Also, this is by no means the most efficient way to do this. This is actually very clunky. Especially because for every id in Table1, you are fetching all the rows for Table2 everytime to match. Instead, you would want to fetch all the rows for Table1 once, then all the rows for Table2 once and then match them up. I will leave the optimization to make this faster upto you.
import sqlite3
#connect to the database containing the two tables
conn = sqlite3.connect("<PUT DB FILENAME HERE>")
cur = conn.execute("SELECT id FROM Table1")
for row in cur.fetchall():
row_table1_id = row[0]
cur2 = conn.execute("SELECT id, class FROM Table2")
for row1 in cur2.fetchall():
row_table2_id = row1[0] # catches the id
row_table2_class = row1[1] # catches the name
if row_table1_id == row_table2_id:
print "yes" # as a test for me to see the loop worked
new_class = row_table2_class
conn.execute("UPDATE Table1 SET classification=? WHERE id=?", (new_class, row_table1_id))
conn.commit()

How to insert into sqlite table that contains only one column with auto-incremental primary key?

I would like to have in sqlite a "counter" table that always give me a new unique ID. I have managed what I need in the following way. First, I create the following table:
cursor.execute('''create table second (id integer primary key autoincrement, age integer)''')
Then I perform the following sequence of commands:
cursor.execute('''insert into second (age) values (1)''')
cursor.lastrowid
Each time when I execute the above two columns I get a new integer. It is exactly what I need. However, the above solution is not elegant since I use a column ("age") that I do not really need. The reason I used is following. I can create a table that contains only one column with the IDs:
cursor.execute('''create table first (id integer primary key autoincrement)''')
However, the problem is that I cannot manage to insert into this table. The following does not work:
cursor.execute('''insert into first () values ()''')
I get the following error message:
sqlite3.OperationalError: near ")": syntax error
Does anybody knows how to solve the described problem?
This should work:
sqlite> CREATE TABLE first (id integer primary key autoincrement);
sqlite> INSERT INTO first (id) VALUES (null);
sqlite> SELECT * FROM first;
1
sqlite> INSERT INTO first (id) VALUES (null);
sqlite> SELECT * FROM first;
1
2
The documentation says:
If no ROWID is specified on the insert, or if the specified ROWID has a value of NULL, then an appropriate ROWID is created automatically.
So you can either explicitly specify NULL:
INSERT INTO first(id) VALUES(NULL)
or specify no value at all:
INSERT INTO first DEFAULT VALUES

Categories

Resources