I am trying to do a SQLite insert from my python script.
I am getting an error:
table history has 4 columns but 3 values were supplied
The reason there is 3 not 4, is that the first one is my ID. I assumed that as i declared it as a primary key it would auto-increment the value. How do I go about inserting the ID
.py:
c.execute("INSERT INTO history VALUES (?,?,?)", (q[0],t,in))
.db
CREATE TABLE history (id integer primary key, employeeID integer, time datetime, inout varchar);
You either have to provide values for all columns, or name the columns you are inserting into explicitly. SQLite will not go and guess what columns you provided values for, you need to be explicit about them.
You can use a NULL to have SQLite insert an auto-generated id for you:
c.execute("INSERT INTO history VALUES (NULL,?,?,?)", (q[0],t,in))
or you can name the 3 columns you are inserting into explicitly:
c.execute("INSERT INTO history (employeeID, time, inout) VALUES (?,?,?)", (q[0],t,in))
Related
I am creating a database from different CSV files. After doing this I have tried to define the primary key table by table but I got an error.
c.execute("ALTER TABLE patient_data ADD PRIMARY KEY (ID);").fetchall()
OperationalError: near "PRIMARY": syntax error
Maybe the best thing to avoid this error is to define the primary key when the table is create but I dont know how to do that. I have been working with python for a few years but today is my first approach with SQL.
This is the code I use to import a CSV to a table
c.execute('''DROP TABLE IF EXISTS patient_data''')
c.execute(''' CREATE TABLE patient_data (ID, NHS_Number,Full_Name,Gender, Birthdate, Ethnicity, Postcode)''')
patients_admitted.to_sql('patient_data', conn, if_exists='append', index = False)
c.execute('''SELECT * FROM patient_data''').fetchall()
This is too long for a comment.
If your table does not have data, just re-create it with the primary key definition.
If your table does have data, you cannot add a primary key in one statement. Why not? The default value is either NULL or constant. And neither is allowed as a primary key.
And finally, SQLite does not allow you to add a primary key to an existing table. The solution is to copy the data to another table, recreate the table with the structure you want, and then copy the data back in.
I am writing a code for a program that connects to Database file12.sqllite3 and creates table 'student3' to store ID as primary key and Name. Also, I want that if the file is not created, then it should be created.
But my code shows error-->
sqlite3.IntegrityError: UNIQUE constraint failed: student3.ID
What is wrong?
Why is this error coming? Where has the UNIQUE constraint failed?
Here is my code :
--- import sqlite3;
conn=sqlite3.connect('file12.sqlite3');
c=conn.cursor();``
c.execute("CREATE TABLE IF NOT EXISTS student3(ID integer
PRIMARY KEY, NAME text)");
c.execute("INSERT INTO student3 VALUES(11,'Tendo Sinha')");
c.execute("INSERT INTO student3 VALUES(12,'Harsh Gupta')");
c.execute("INSERT INTO student3 VALUES(13,'Vishwas Kumar')");
c.execute("INSERT INTO student3 VALUES(14,'Goel')");
c.execute("INSERT INTO student3 VALUES(15,'Alok')");
conn.commit();
c.execute("SELECT * from student3");
print(c.fetchall());
c.execute("SELECT ID from student3")
print(c.fetchmany(4));
c.execute("UPDATE student3 SET Name='Bhanu' where ID=14");
print(c.fetchall());
How to rectify the error -->
sqlite3.IntegrityError: UNIQUE constraint failed: student3.ID
Your code fails if you run it twice : the first time it will run just fine as you are inserting with available ID values but as soon as you run it again, you try to insert on ID values that already exist, that is what causes the exception.
The primary key values are meant to be unique, there cannot be any duplicates
I would recommend inserting this way : c.execute("INSERT INTO student3 VALUES(NULL,'Alok')"); with a NULL instead of a given value for the ID. This allows SQLite to insert a value on an available value. You can therefor insert as many students as you wish with same or different names without getting the exception.
However, beware of your c.execute("UPDATE student3 SET Name='Bhanu' where ID=14"); if you use the NULL insert method as you will not know the ID's in advance, you may need to search on the name itself rather than the ID or get the ID as you insert and store it as a variable for later use
Note : Since SQLite3 already does the creation of the file if it doesn't exist, you do not need to do anything there
Code:
import sqlite3
c = sqlite3.Connection(':memory:')
c.execute('CREATE TABLE foo(a INTEGER, b VARCHAR(8), PRIMARY KEY(a, b))')
c.execute('INSERT INTO foo(a) VALUES (1)')
c.execute('INSERT INTO foo(a) VALUES (1)')
print(c.execute('SELECT * FROM foo').fetchall())
Output:
[(1, None), (1, None)]
Why is SQLite inserting rows with duplicate primary keys? How do I fix this?
SQL PK (PRIMARY KEY) means UNIQUE NOT NULL. You shouldn't expect to be able to have a NULL in a value for a PK, let alone only one. You should declare PK columns NOT NULL and not put NULL in them.
SQL As Understood By SQLite:
Each row in a table with a primary key must have a unique combination of values in its primary key columns. For the purposes of determining the uniqueness of primary key values, NULL values are considered distinct from all other values, including other NULLs. If an INSERT or UPDATE statement attempts to modify the table content so that two or more rows have identical primary key values, that is a constraint violation.
According to the SQL standard, PRIMARY KEY should always imply NOT NULL. Unfortunately, due to a bug in some early versions, this is not the case in SQLite. Unless the column is an INTEGER PRIMARY KEY or the table is a WITHOUT ROWID table or the column is declared NOT NULL, SQLite allows NULL values in a PRIMARY KEY column. SQLite could be fixed to conform to the standard, but doing so might break legacy applications. Hence, it has been decided to merely document the fact that SQLite allowing NULLs in most PRIMARY KEY columns.
Since NULL in a PK is against SQL, it seems moot what SQLite then chooses to do when constraining and manipulating tables with NULLs in a PK. But it uses the usual SQL interpretation that NULL is not equal to NULL for purposes of UNIQUE. This is like when you declare a column set UNIQUE NULL. So as a constraint, SQLite PK is a synonym for UNIQUE instead of UNIQUE NOT NULL.
A UNIQUE constraint is similar to a PRIMARY KEY constraint, except that a single table may have any number of UNIQUE constraints. For each UNIQUE constraint on the table, each row must contain a unique combination of values in the columns identified by the UNIQUE constraint. For the purposes of UNIQUE constraints, NULL values are considered distinct from all other values, including other NULLs.
SQLite, like many other SQL databases, considers two NULLs as different values for the purposes of uniqueness (partially because, in SQL, NULL == NULL is false).
I don't believe there is a way to alter this behavior. As a workaround, you can use an empty string in column b as "no value".
I'm trying to get a rowid if a data row exists. What I have now is
row_id = self.dbc.cursor.execute("SELECT ROWID FROM Names where unq_id=?",(namesrow['unq_id'],)).fetchall()[0][0]
where namesrow is a dictionary of column names with corresponding data to fill into the table. The problem is this prints 'unq_id' when runs and I'm not sure how to get rid of it.
I'm using sqlite3 and python. Any help's appreciated!
quoting the sqlite documentation:
With one exception noted below, if a rowid table has a primary key
that consists of a single column and the declared type of that column
is "INTEGER" in any mixture of upper and lower case, then the column
becomes an alias for the rowid.
So if your unq_id is the integer primary key in this table, then rowid and unq_id will be the same field.
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