This question already has answers here:
Suggested way to run multiple sql statements in python?
(9 answers)
Closed 1 year ago.
I am building an application with Flask/mysql. I have a raw SQL script needed to seed the database. If I enter a SQL shell and run the command, it works without issues. When I run it from Flask, I am getting an error:
(1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DROP TABLE IF EXISTS board_symbol; \n DROP TABLE IF EXISTS symbol; \n ' at line 2")
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
My flask application is very simple, two files. The first, app.py:
from flask import Flask
from db import create_db, seed_db
app = Flask(__name__)
db = create_db(app)
conn = db.connect()
seed_db(conn)
#app.route("/")
def index():
return "Hello world!"
The second, db.py:
from flaskext.mysql import MySQL
def create_db(app):
app.config["MYSQL_DATABASE_USER"] = "root"
app.config["MYSQL_DATABASE_PASSWORD"] = "mysqluser"
app.config["MYSQL_DATABASE_DB"] = "fault_tree"
app.config["MYSQL_DATABASE_HOST"] = "localhost"
mysql = MySQL()
mysql.init_app(app)
return mysql
def seed_db(conn):
try:
cursor = conn.cursor()
cursor.execute("""
DROP TABLE IF EXISTS symbol_connection;
DROP TABLE IF EXISTS board_symbol;
DROP TABLE IF EXISTS symbol;
DROP TABLE IF EXISTS board;
DROP TABLE IF EXISTS symbol_type;
CREATE TABLE IF NOT EXISTS board (
id INTEGER NOT NULL AUTO_INCREMENT,
name VARCHAR(100),
description VARCHAR(500),
PRIMARY KEY(id)
);
CREATE TABLE IF NOT EXISTS symbol_type (
id INTEGER NOT NULL AUTO_INCREMENT,
type VARCHAR(30),
PRIMARY KEY(id)
);
CREATE TABLE IF NOT EXISTS symbol (
id INTEGER NOT NULL AUTO_INCREMENT,
name VARCHAR(100),
description VARCHAR(200),
type INT,
child_board INT,
PRIMARY KEY(id),
FOREIGN KEY(type) REFERENCES symbol_type(id) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY(child_board) REFERENCES board(id) ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE TABLE IF NOT EXISTS board_symbol (
board_id INTEGER,
symbol_id INTEGER,
FOREIGN KEY(board_id) REFERENCES board(id) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY(symbol_id) REFERENCES symbol(id) ON DELETE CASCADE ON UPDATE CASCADE,
PRIMARY KEY(board_id, symbol_id)
);
CREATE TABLE IF NOT EXISTS symbol_connection (
board_id INTEGER NOT NULL,
start_symbol INT NOT NULL,
destination_symbol INT NOT NULL,
PRIMARY KEY(start_symbol, destination_symbol),
FOREIGN KEY(board_id) REFERENCES board(id) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY(start_symbol) REFERENCES symbol(id) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY(destination_symbol) REFERENCES symbol(id) ON DELETE CASCADE ON UPDATE CASCADE
);
INSERT INTO board(name, description) VALUES('test_board', 'test_board');
INSERT INTO symbol_type(type) VALUES('Event/basic');
INSERT INTO symbol_type(type) VALUES('Event/conditioning');
INSERT INTO symbol_type(type) VALUES('Event/intermediate');
INSERT INTO symbol_type(type) VALUES('Event/remote basic');
INSERT INTO symbol_type(type) VALUES('Event/underdeveloped');
INSERT INTO symbol_type(type) VALUES('Gate/and');
INSERT INTO symbol_type(type) VALUES('Gate/or');
INSERT INTO symbol_type(type) VALUES('Gate/priority and');
INSERT INTO symbol_type(type) VALUES('Gate/priority or');
INSERT INTO symbol_type(type) VALUES('Gate/exclusive or');
INSERT INTO symbol_type(type) VALUES('Transfer');
INSERT INTO symbol(name, description, type) VALUES('Test event', 'test basic event', 1);
INSERT INTO symbol(name, description, type) VALUES('Test and gate', 'test and gate', 6);
INSERT INTO symbol(name, description, type) VALUES('Test intermediate event', 'test int event', 3);
INSERT INTO symbol(name, description, type) VALUES('Test or gate', 'test or gate', 7);
INSERT INTO board_symbol(board_id, symbol_id) VALUES(1, 1);
INSERT INTO board_symbol(board_id, symbol_id) VALUES(1, 2);
INSERT INTO board_symbol(board_id, symbol_id) VALUES(1, 3);
INSERT INTO board_symbol(board_id, symbol_id) VALUES(1, 4);
INSERT INTO symbol_connection(board_id, start_symbol, destination_symbol) VALUES(1, 1, 2);
INSERT INTO symbol_connection(board_id, start_symbol, destination_symbol) VALUES(1, 1, 3);
INSERT INTO symbol_connection(board_id, start_symbol, destination_symbol) VALUES(1, 3, 4);
SELECT * FROM symbol_connection;
SELECT * FROM symbol_type;
SELECT * FROM board_symbol;
SELECT * FROM symbol;
SELECT * FROM board;
""")
data = cursor.fetchall()
print(data)
except Exception as e:
print(e)
# raise Exception("Problem initializing MySQL database - check that fault_tree database exists and user root has access")
This is set up using a local database named fault_tree, with creds as listed in db.py if helpful for troubleshooting.
By default, you can only do one SQL statement per invocation of cursor.execute().
To run multiple SQL statements separated by semicolons, use cursor.execute("""...""", multi=True)
See https://instructobit.com/tutorial/130/Executing-multi-query-.sql-files-using-MySQL-connector-in-Python for a tutorial.
Related
I want to create a table through a python script running sql but want to clear any ones with the same name which may already exist. The below code produces an error "mysql.connector.errors.ProgrammingError: 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CREATE TABLE groceries(id int(11) NOT NULL AUTO_INCREMENT,item varchar(25) D' at line 1".
I can get the code to work line by line individually but not sure how to combine it all into one script so it runs at the same time through python.
import mysql.connector
db = mysql.connector.connect(
host = "localhost",
user= "test",
password = 'test',
database = "grocery"
)
cursor = db.cursor()
sql = "DROP TABLE IF EXISTS groceries, CREATE TABLE groceries(`id` int(11) NOT NULL AUTO_INCREMENT,`item` varchar(25) DEFAULT NULL, `name` varchar(25) DEFAULT NULL, `quantity` int(11) DEFAULT NULL,PRIMARY KEY (`id`))"
cursor.execute(sql)
You are getting a syntax error because you using commas instead of semicolons for separating the DROP TABLE IF EXISTS and CREATE TABLE statements
If you separate your SQL statements with semicolons, you'll be able to execute your code.
In addition, you need to tell your connector that there are multiple statements with multi=true
The final code looks like:
sql = """
DROP TABLE IF EXISTS groceries;
CREATE TABLE groceries(
`id` int(11) NOT NULL AUTO_INCREMENT,
`item` varchar(25) DEFAULT NULL,
`name` varchar(25) DEFAULT NULL,
`quantity` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
)
"""
cursor.execute(sql, multi=true)
Consider this code:
import pymysql
db= pymysql.connect("localhost","root","","raspi")
cursor = db.cursor()
cursor.execute("INSERT INTO access(username)VALUES('hello')")
db.commit()
db.close()
when I run it I'll get this error:
C:\Python36\lib\site-packages\pymysql\cursors.py:165: Warning: (1364,"Field'salt' doesn't have a default value")result = self._query(query)
How do I ignore pymysql warnings?
Reason why you're getting that error is because your salt field is not allowing NULL values but you're trying to insert them, probably your table creation sql code looks something like this:
CREATE TABLE `access` (
`username` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
...
`salt` VARCHAR(50) NOT NULL COLLATE 'utf8_unicode_ci'
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
;
If you just wanted to allow NULL values for that field maybe your SQL code would need to be change into something like:
...
`salt` VARCHAR(50) NULL COLLATE 'utf8_unicode_ci'
...
Anyway, if you still insist to keep your original db structure and want to learn how filter out warnings, here's a possible way to you could do it:
import pymysql
import warnings
db = pymysql.connect("localhost", "root", "", "raspi")
with warnings.catch_warnings():
warnings.simplefilter("ignore")
cursor = db.cursor()
cursor.execute("INSERT INTO access(username)VALUES('hello')")
db.commit()
db.close()
For more information, take a look to the warnings docs
I am working on a project in which I am using python to store sensor data in a SQLite Database.
If the table does not exists it will be created like this:
query_db('create table if not exists %s (id INTEGER PRIMARY KEY AUTOINCREMENT, value double, datetimestamp DATETIME, user CHAR(2));' % (sensor_name+'_VALUES'))
Next I want to insert the values from a HTTP Post Request:
sensor_value = request.json['value']
dtstamp = request.json['timestamp']
user_name = request.json['user']
result = query_db('INSERT INTO %s ("value", "datetimestamp", "user") VALUES ( "%s" ,"%s" , "%s");' % (sensor_name + '_VALUES', sensor_value, dtstamp, user_name))
But I don't get an error and it also seems like the insert is not executed.
The request looks like this:
{
"value" : 22,
"timestamp" : "2017-02-17 22:22:22",
"user" : "TE"
}
Anyone know why?
You need to commit the transaction to persist the changes in the database:
db.commit()
Here is some additional information about why and when do you need to commit:
python sqlite3, how often do I have to commit?
I'm trying do delete a user from my database using python and sqlite.
import sqlite3
database_connection = sqlite3.connect('test.db')
delete_username_input = input("Which user you would like to delete?\n\n")
sql = ("DELETE * from USERS where USERNAME = ?")
args = (delete_username_input)
database_connection.execute(sql, args)
database_connection.commit()
database_connection.close()
When running the code above, I get the following error:
sqlite3.OperationalError: near "*": syntax error
Any idea what might be causing this error?
The table that I use has been created using the following syntax:
conn.execute('''CREATE TABLE USERS
(ID INTEGER PRIMARY KEY AUTOINCREMENT,
USERNAME TEXT NOT NULL,
PASSWORD TEXT NOT NULL,
WINS FLOAT NOT NULL,
LOSES FLOAT NOT NULL,
GAMESPLAYED FLOAT NOT NULL,
WINPERCENT FLOAT NOT NULL );''')
Any help will be appreciated.
Your SQL syntax is wrong. It should be
DELETE from USERS where USERNAME = ?
without the *
Check it out here
Python/Flask:
cur = conn.cursor()
cur.execute('CREATE TABLE IF NOT EXISTS users (email TEXT NOT NULL UNIQUE, password TEXT)')
print('Table created')
Then in another method
def create_user(email, hashedpw):
try:
cur.execute('INSERT INTO users VALUES (?, ?)', (email, hashedpw))
conn.commit()
return "works"
except:
print(str(sqlite3.Error))
return None
Even if I input the same email 10 times it still records the data in the database and doesn't give an error. I clearly set it to UNIQUE then why isnt it working?
Your syntax looks good so only explanation that comes to mind is:
You already have a table named users in your database which doesn't have the UNIQUE constraint and since you are using IF NOT EXISTS, that table remains as it is.