sqlite3 prints without explicit command - python

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.

Related

Change VARCHAR length of columns created dynamically in SQL table using sqlalchemy

I need to create columns dynamically in table1 based on the values retrieved from the form. I am using sqlalchemy to do the same and using the below code:
engine.execute('ALTER TABLE %s ADD COLUMN %s %s;' % ('table1', col_name, "VARCHAR(100)"))
In the above statement:
table1: name of the table we are inserting the column dynamically.
col_name: string containing the column name that is to be inserted.
VARCHAR(100): column type
The above code runs without any error and the new column is added. However, all the columns being created have the datatype as VARCHAR(60) in the table. I need to increase the length of column. Also, I'm not using flask-sqlalchemy.
Any ideas what might be causing the problem.

IntegrityError: datatype mismatch

I know this question was asked before here. The reason was a mismatch between the SQL schema and the inserted data.
So I made sure that the SQL schema matches my inserted data. But I get an IntegrityError Error.
Could you tell me, where the datatype mismatch could be?
conn = sqlite3.connect("contdata_sql.db")
c = conn.cursor() # ich brauche ein Curser Object
c.execute('''CREATE TABLE imbalanced ([ChannelStatusResult] INTEGER PRIMARY KEY,
[Channels] text,
[Channel] text,
[Channel_Type] text,
[Channel_Name] text)''')
np.array(map(str, array_2d_sql))# make sure all values are strings
print("array_2d_sql = ",array_2d_sql)
# = ['ChannelStatusResult' 'Channels' 'Channel' 'ChannelName'
#'REST_RECEIVER_LOOKUP']
# ['ChannelStatusResult' 'Channels' 'Channel' 'ChannelID'
# '87842bb134ba31cf9c43685fabcd2eac']
...
print("array_2d_sql.shape = ",array_2d_sql.shape) # = (461, 5)
c.executemany('''INSERT INTO imbalanced VALUES (?,?,?,?,?)''', array_2d_sql) # Error occures here!!!
Any type of data can be stored in any type of column , with one exception, the exception being that a column defined specifically as INTEGER PRIMARY KEY (with or without AUTOINCREMENT) is an alias of the rowid column, which must be an integer. If it is not an integer then that is when you get the datatype mismatch error.
As such the cause is that the first value of your insert is not an integer.
Typically INTEGER PRIMARY KEY is used for a self-generated unique identifier and the value is not supplied but used as a means of uniquely identifying a row. In such a usage a value is not provided (or null can be used) and SQLite generates a value (1 for the first, then likely 2, then 3 and so on).
The actual best fix is unclear, other than to say that you probably need to define the [ChannelStatusResult] differently, so that it is not INTEGER PRIMARY KEY and therefore that the column is not an alias of the rowid column.
If you used
c.execute('''CREATE TABLE imbalanced ([ChannelStatusResult] INT PRIMARY KEY,
[Channels] text,
[Channel] text,
[Channel_Type] text,
[Channel_Name] text)''')
As INTEGER PRIMARY KEY isn't coded then the [ChannelStatusResult] column is not an alias of the rowid and thus can be any value. The rowid column is then hidden but still usable e.g. you could use SELECT *,rowid FROM any_table.
However, without being aliased, the rowid can be changed by VACUUM and therefore cannot be relied upon to not change (and should therefore not be used for relationships (a common and efficient means of building relationships between tables)).
Note although INT PRIMARY KEY may resolve the issue, this may not be the best fix.

Combine CREATE TABLE, ADD COLUMNS, PRIMARY KEY, AS SELECT, and WHERE into one operation

I need to create a copy of a table (if it does not already exist), and this copy needs one of the existing columns to become a primary key.
Currently I have the following SQL commands (in a Python script):
CREATE TABLE IF NOT EXISTS FilteredTable AS SELECT * FROM RawTable WHERE <cond>
ALTER TABLE FilteredTable ADD COLUMN IF NOT EXISTS (NewCol1 TEXT, etc TEXT)
ALTER TABLE FilteredTable ADD PRIMARY KEY (ColumnNameFromRaw)
This works fine the first time around, but of course when run again after the table already exists it complains that a primary key already exists. Is there a way to combine the ADD PRIMARY KEY with the CREATE TABLE ... command so that it only attempts to set the primary key when the table needs to be created?
EDIT
Python code can be used.
SQL: 10.1.23-MariaDB
Python: 2.7
You can add extra columns and indexes in the CREATE TABLE command even when coming from a SELECT. So do it all in one step:
CREATE TABLE IF NOT EXISTS FilteredTable (
NewCol1 TEXT, etc TEXT,
PRIMARY KEY (ColumnNameFromRaw)
) AS SELECT * FROM RawTable WHERE <cond>
Note: the column names are matched up by name. That is, if * has a NewCol1, it will go into that TEXT column. If not, then NewCol1 will be empty.
This isn't quite as clean as a purely SQL solution, but it works in the event that you're accessing SQL indirectly like so...
# ...
# (New table creation)
# ...
# Display column data for specified table
curs.execute("SHOW COLUMNS FROM NewTable")
# Collect the data as a tuple of tuples containing chart rows
colsNew = curs.fetchall()
# Iterate through each table column (row in the chart)
for col in colsNew:
# Check to see if Key is not "PRI" for the Field (Column) "DesiredColumn"
if (col[0] == "DesiredColumn") and (col[3] != "PRI"):
# Make DesiredColumn the primary key
curs.execute("ALTER TABLE NewTable ADD PRIMARY KEY (DesiredColumn)")

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

creating blank field and receving the INTEGER PRIMARY KEY with sqlite, python

I am using sqlite with python. When i insert into table A i need to feed it an ID from table B. So what i wanted to do is insert default data into B, grab the id (which is auto increment) and use it in table A. Whats the best way receive the key from the table i just inserted into?
As Christian said, sqlite3_last_insert_rowid() is what you want... but that's the C level API, and you're using the Python DB-API bindings for SQLite.
It looks like the cursor method lastrowid will do what you want (search for 'lastrowid' in the documentation for more information). Insert your row with cursor.execute( ... ), then do something like lastid = cursor.lastrowid to check the last ID inserted.
That you say you need "an" ID worries me, though... it doesn't matter which ID you have? Unless you are using the data just inserted into B for something, in which case you need that row ID, your database structure is seriously screwed up if you just need any old row ID for table B.
Check out sqlite3_last_insert_rowid() -- it's probably what you're looking for:
Each entry in an SQLite table has a
unique 64-bit signed integer key
called the "rowid". The rowid is
always available as an undeclared
column named ROWID, OID, or _ROWID_ as
long as those names are not also used
by explicitly declared columns. If the
table has a column of type INTEGER
PRIMARY KEY then that column is
another alias for the rowid.
This routine returns the rowid of the
most recent successful INSERT into the
database from the database connection
in the first argument. If no
successful INSERTs have ever occurred
on that database connection, zero is
returned.
Hope it helps! (More info on ROWID is available here and here.)
Simply use:
SELECT last_insert_rowid();
However, if you have multiple connections writing to the database, you might not get back the key that you expect.

Categories

Resources