I've finished making some SQLite tables and am executing the instructions. When executing the instructions, the following error has come up:
sqlite3.OperationalError: near "Category": syntax error
Most of my tables use the same sort of format, below is an example of one such table.
CategoryTableSQL = """ CREATE TABLE IF NOT EXISTS Category(
CategoryID integer PRIMARY KEY AUTOINCREMENT
Category text NOT NULL
);"""
databaseNewTable(Connection, CategoryTableSQL)
You forgot a comma between the declaration of your table fields in your SQL-statement: It should be like this. Always use comma's to seperate the field-creation statements. Except of course, for the last field you create =). Also, I would take care in naming your fields the same name as your tables. To prevent confusion. Just my two cents
CREATE TABLE IF NOT EXISTS Category(
CategoryID integer PRIMARY KEY AUTOINCREMENT,
Category text NOT NULL
);
I think, You just need to add the ',' symbol after the AUTOINCREMENT word. :-)
Like this:
CategoryTableSQL = """ CREATE TABLE IF NOT EXISTS Category(
CategoryID integer PRIMARY KEY AUTOINCREMENT,
Category text NOT NULL
);"""
databaseNewTable(Connection, CategoryTableSQL)
Related
I'm basically building a secured online diary application with Flask. However my Python source code returns a syntax error when I try to test the app. I can't detect what's wrong with the syntax. Your help will be appreciated.
I'm attaching a screenshot of the error. And here's my SQL database's schema:
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
username TEXT NOT NULL,
hash TEXT NOT NULL
);
CREATE TABLE sqlite_sequence(name,seq);
CREATE UNIQUE INDEX username ON users (username);
CREATE TABLE diaries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
name TEXT NOT NULL,
time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
title TEXT NOT NULL,
description TEXT NOT NULL,
img_url TEXT,
FOREIGN KEY(user_id) REFERENCES users(id)
);
New error: unsupported value
It is INSERT statement that causes error.
Well, not the insert itself but the way you're using it.
Values should be passed as a tuple (values between "(" and ")")
So, you need to update db.execute line with something like that
db.execute("insert into table_name(col1, col2) values(?, ?)", (col1_val, col2_val))
UPD. regarding the error on second screenshot.
db.execute("Select...) does not return a value but a set of values.
So, you might wanted to use fetchone() as in docs
res = cur.execute('SELECT count(rowid) FROM stocks') # gets you set records
print(res.fetchone()) # get first record
Anyway, check the docs I provided you link to with.
I am trying to create a number of tables with different names (of course) but sharing the same schema. For this purpose, I am using executemany on a Cursor object as follows:
tables = ['Meanings', 'Synonyms', 'Antonyms', 'Examples', 'Phrases',
'Pronunciations', 'Hyphenations']
create_table_query = '''CREATE TABLE (?) (
id INTEGER NOT NULL,
text TEXT,
word_id INTEGER NOT NULL,
PRIMARY KEY id,
FOREIGN KEY(word_id) REFERENCES Word(id)
)'''
cursor.executemany(create_table_query, tables)
When I execute this snippet, I get the following error message:
OperationalError: near "(": syntax error
I am having trouble fixing the bug here with my SQL since I find the error message to be not descriptive enough. I have tried the following queries but I am unable to develop the understanding of their success and my query's failure:
create_table_query_1 = '''CREATE TABLE {} (
id INTEGER NOT NULL,
text TEXT,
word_id INTEGER NOT NULL,
PRIMARY KEY id,
FOREIGN KEY(word_id) REFERENCES Word(id)
)''' # Syntax error near "id"
create_table_query_2 = '''CREATE TABLE (?) (
id INTEGER PRIMARY KEY,
text TEXT,
word_id INTEGER NOT NULL,
FOREIGN KEY(word_id) REFERENCES Word(id)
)''' # Syntax error near "("
create_table_query_1 = '''CREATE TABLE {} (
id INTEGER PRIMARY KEY,
text TEXT,
word_id INTEGER NOT NULL,
FOREIGN KEY(word_id) REFERENCES Word(id)
)''' # works with string formatting
Also, what are other efficient(in terms of time) ways to achieve the same?
To put my comment into an answer and expand on it: you cannot parametrize table nor column names. I was unable to find any documentation on this...
In a couple of the other examples you have extra parens/brackets that SQLite doesn't need.
So the solution, as you've found, is to use string substitution for the table names as in your final example.
Here's an example with a loop over all of your tables:
for table in tables:
cursor.execute('''CREATE TABLE {} (
id INTEGER PRIMARY KEY,
text TEXT,
word_id INTEGER NOT NULL,
FOREIGN KEY(word_id) REFERENCES Word(id)
)'''.format(table))
I am not completely clear on why you want different tables for the different types of words, though, as this would seem to go against the principles of database design.
I'm working with sqlite3 on python 2.7 and I am facing a problem with a many-to-many relationship. I have a table from which I am fetching its primary key like this
current.execute("SELECT ExtensionID FROM tblExtensionLookup where ExtensionName = ?",[ext])
and then i am fetching another primary key from another table
current.execute("SELECT HostID FROM tblHostLookup where HostName = ?",[host])
now what i am doing is i have a third table with these two keys as foreign keys and i inserted them like this
current.execute("INSERT INTO tblExtensionHistory VALUES(?,?)",[Hid,Eid])
The problem is i don't know why but the last insertion is not working it keeps giving errors. Now what i have tried is:
First I thought it was because I have an autoincrement primary id for the last mapping table which I didn't provide, but isn't it supposed to consider itself as it's auto incremented? However I went ahead and tried adding Null,None,0 but nothing works.
Secondly I thought maybe because i'm not getting the values from tables above so I tried printing it out and it shows so it works.
Any suggestions what I am doing wrong here?
EDIT :
When i don't provide primary key i get error as
The table has three columns but you provided only two values
and when i do provide them as None,Null or 0 it says
Parameter 0 is not supported probably because of unsupported type
I tried implementing the #abarnet way but still keeps saying parameter 0 not supported
connection = sqlite3.connect('WebInfrastructureScan.db')
with connection:
current = connection.cursor()
current.execute("SELECT ExtensionID FROM tblExtensionLookup where ExtensionName = ?",[ext])
Eid = current.fetchone()
print Eid
current.execute("SELECT HostID FROM tblHostLookup where HostName = ?",[host])
Hid = current.fetchone()
print Hid
current.execute("INSERT INTO tblExtensionHistory(HostID,ExtensionID) VALUES(?,?)",[Hid,Eid])
EDIT 2 :
The database schema is :
table 1:
CREATE TABLE tblHostLookup (
HostID INTEGER PRIMARY KEY AUTOINCREMENT,
HostName TEXT);
table2:
CREATE TABLE tblExtensionLookup (
ExtensionID INTEGER PRIMARY KEY AUTOINCREMENT,
ExtensionName TEXT);
table3:
CREATE TABLE tblExtensionHistory (
ExtensionHistoryID INTEGER PRIMARY KEY AUTOINCREMENT,
HostID INTEGER,
FOREIGN KEY(HostID) REFERENCES tblHostLookup(HostID),
ExtensionID INTEGER,
FOREIGN KEY(ExtensionID) REFERENCES tblExtensionLookup(ExtensionID));
It's hard to be sure without full details, but I think I can guess the problem.
If you use the INSERT statement without column names, the values must exactly match the columns as given in the schema. You can't skip over any of them.*
The right way to fix this is to just use the column names in your INSERT statement. Something like:
current.execute("INSERT INTO tblExtensionHistory (HostID, ExtensionID) VALUES (?,?)",
[Hid, Eid])
Now you can skip any columns you want (as long as they're autoincrement, nullable, or otherwise skippable, of course), or provide them in any order you want.
For your second problem, you're trying to pass in rows as if they were single values. You can't do that. From your code:
Eid = current.fetchone()
This will return something like:
[3]
And then you try to bind that to the ExtensionID column, which gives you an error.
In the future, you may want to try to write and debug the SQL statements in the sqlite3 command-line tool and/or your favorite GUI database manager (there's a simple extension that runs in for Firefox if you don't want anything fancy) and get them right, before you try getting the Python right.
* This is not true with all databases. For example, in MSJET/Access, you must skip over autoincrement columns. See the SQLite documentation for how SQLite interprets INSERT with no column names, or similar documentation for other databases.
I am trying to add an 'id' primary key column to an already existing MySQL table using alembic. I tried the following...
op.add_column('mytable', sa.Column('id', sa.Integer(), nullable=False))
op.alter_column('mytable', 'id', autoincrement=True, existing_type=sa.Integer(), existing_server_default=False, existing_nullable=False)
but got the following error
sqlalchemy.exc.OperationalError: (OperationalError) (1075, 'Incorrect table definition; there can be only one auto column and it must be defined as a key') 'ALTER TABLE mytable CHANGE id id INTEGER NOT NULL AUTO_INCREMENT' ()
looks like the sql statement generated by alembic did not add PRIMARY KEY at the end of the alter statement. Could I have missed some settings?
Thanks in advance!
I spent some time digging through the alembic source code, and this doesn't seem to be supported. You can specify primary keys when creating a table, but not when adding columns. In fact, it specifically checks and won't let you (link to source):
# from alembic.operations.toimpl.add_column, line 132
for constraint in t.constraints:
if not isinstance(constraint, sa_schema.PrimaryKeyConstraint):
operations.impl.add_constraint(constraint)
I looked around, and adding a primary key to an existing table may result in unspecified behavior - primary keys aren't supposed to be null, so your engine may or may not create primary keys for existing rows. See this SO discussion for more info: Insert auto increment primary key to existing table
I'd just run the alter query directly, and create primary keys if you need to.
op.execute("ALTER TABLE mytable ADD id INT PRIMARY KEY AUTO_INCREMENT;")
If you really need cross-engine compatibility, the big hammer would be to (1) create a new table identical to the old one with a primary key, (2) migrate all your data, (3)delete the old table and (4) rename the new table.
Hope that helps.
You have to remove the primary key that is in the table and then create a new one that includes all columns that you want as the primary key.
eg. In psql use \d <table name> to define the schema, then check the primary key constraint.
Indexes:
"enrollments_pkey" PRIMARY KEY, btree (se_crs_id, se_std_id)
then use this information in alembic
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('enrollments', sa.Column(
'se_semester', sa.String(length=30), nullable=False))
op.drop_constraint('enrollments_pkey', 'enrollments', type_='primary')
op.create_primary_key('enrollments_pkey', 'enrollments', [
'se_std_id', 'se_crs_id', 'se_semester'])
The results after running \d enrollments should be updated to
Indexes:
"enrollments_pkey" PRIMARY KEY, btree (se_std_id, se_crs_id, se_semester)
This solution worked fine for me.
I am using sqlite with python 2.5. I get a sqlite error with the syntax below. I looked around and saw AUTOINCREMENT on this page http://www.sqlite.org/syntaxdiagrams.html#column-constraint but that did not work either. Without AUTO_INCREMENT my table can be created.
An error occurred: near "AUTO_INCREMENT": syntax error
CREATE TABLE fileInfo
(
fileId int NOT NULL AUTO_INCREMENT,
name varchar(255),
status int NOT NULL,
PRIMARY KEY (fileId)
);
This is addressed in the SQLite FAQ. Question #1.
Which states:
How do I create an AUTOINCREMENT
field?
Short answer: A column declared
INTEGER PRIMARY KEY will
autoincrement.
Here is the long answer: If you
declare a column of a table to be
INTEGER PRIMARY KEY, then whenever you
insert a NULL into that column of the
table, the NULL is automatically
converted into an integer which is one
greater than the largest value of that
column over all other rows in the
table, or 1 if the table is empty. (If
the largest possible integer key,
9223372036854775807, then an unused
key value is chosen at random.) For
example, suppose you have a table like
this:
CREATE TABLE t1( a INTEGER PRIMARY
KEY, b INTEGER ); With this table,
the statement
INSERT INTO t1 VALUES(NULL,123); is
logically equivalent to saying:
INSERT INTO t1 VALUES((SELECT max(a)
FROM t1)+1,123); There is a function
named sqlite3_last_insert_rowid()
which will return the integer key for
the most recent insert operation.
Note that the integer key is one
greater than the largest key that was
in the table just prior to the insert.
The new key will be unique over all
keys currently in the table, but it
might overlap with keys that have been
previously deleted from the table. To
create keys that are unique over the
lifetime of the table, add the
AUTOINCREMENT keyword to the INTEGER
PRIMARY KEY declaration. Then the key
chosen will be one more than than the
largest key that has ever existed in
that table. If the largest possible
key has previously existed in that
table, then the INSERT will fail with
an SQLITE_FULL error code.
It looks like AUTO_INCREMENT should be AUTOINCREMENT see http://www.sqlite.org/syntaxdiagrams.html#column-constraint
You could try
CREATE TABLE fileInfo
(
fileid INTEGER PRIMARY KEY AUTOINCREMENT,
name STRING,
status INTEGER NOT NULL
);
We just changed the order from
NOT NULL, AUTO_INCREMENT
to
AUTO_INCREMENT NOT NULL,
an example :
cursor.execute("CREATE TABLE users(\
user_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\
user_name VARCHAR(100) NOT NULL)")