Forums

Python - MySQL puzzle

Hi All, I've been struggling with writing a comment to the database. The table only has ID and content columns, from the tutorial. Because I found that SqlAlchemy didn't handle simple dates like I want, I reverted to interacting directly with the database. I have no problems writing to other tables of numerous columns, but this Comments table with just one data column is frustrating me.

My Code:

import pytz # datetime conversion
import dbaccess as DBconfig

import mysql.connector

#establishing the connection
conn = mysql.connector.connect(
   user=DBconfig.username, password=DBconfig.password, host=DBconfig.hostname, database=DBconfig.databasename)

#Creating a cursor object using the cursor() method
cursor = conn.cursor()

# Prepare SQL query to INSERT a record into the balance table
comment_sql = "INSERT INTO comments (content) values (%s)"

# current date and time
from datetime import datetime
timezone = pytz.timezone('Europe/Berlin')
now = datetime.utcnow().astimezone(tz=timezone).strftime('%Y-%m-%d %H:%M')

message = str(now) + " Received request"
val = message
cursor.execute(comment_sql,val)
conn.commit()
conn.close()

This code is what I believe I'm generating and it works perfectly in the mysql interface, writing the row as expected:

INSERT INTO comments (content) values ('2022-07-22 20:55:52 Received request");

But in the console window of the Python code, I#m getting this error:

line 23: cursor.execute(comment_sql,val)

Traceback (most recent call last):
  File "/home/pegasus163/mysite/write_comment.py", line 23, in <module>
    cursor.execute(comment_sql,val)
  File "/usr/local/lib/python3.7/site-packages/mysql/connector/cursor_cext.py", line 248, in execute
    prepared = self._cnx.prepare_for_mysql(params)
  File "/usr/local/lib/python3.7/site-packages/mysql/connector/connection_cext.py", line 649, in prepare_for_mysql
    raise ValueError("Could not process parameters")
ValueError: Could not process parameters

Is there some strange issue with just one substitution variable?

mysql> describe comments;
+---------+---------------+------+-----+---------+----------------+
| Field   | Type          | Null | Key | Default | Extra          |
+---------+---------------+------+-----+---------+----------------+
| id      | int(11)       | NO   | PRI | NULL    | auto_increment |
| content | varchar(4096) | YES  |     | NULL    |                |
+---------+---------------+------+-----+---------+----------------+

Thanks for your help

The second argument to cursor.execute needs to be a tuple with the values that you want to insert into your query, not a plain string of the value.

Thanks Glenn, I'm reminded of the George Carlin skit on Noah and God talking about building the ark... "what's a cubit?" I haven't reached the Tuple lesson yet... :) Actually I tried to make it a list and that didn't work.

Thanks Glenn, It's a little goofy looking at first, but since I have only one substitute item, this works:

val = str(now) + " Received request"
cursor.execute(comment_sql,(val,))
conn.commit()
conn.close()

The select query results in

2022-07-23 21:38 Received request

Turns out that it works out great when running from the console, but errors continue when serving a POST request. I've searched and searched for ideas, to no avail. I have tried simpler statements just to get it to work. I don't know if triple double-quotes are needed... The last one here is not using any substitution and even it fails:

#        message = """INSERT INTO comments (content) values ('Received GET request on page')"""
#        message = "INSERT INTO comments (content) values ('2022-07-23 Received GET request on page')"
#        message = "INSERT INTO comments (content) values ('" + "2022-07-23" + " Received GET request on page')"
#        message = "INSERT INTO comments (content) values ('" + str(now) + " Received GET request on page')"
#        message = baseComment + " Received GET request on page')"
        cursor.execute("INSERT INTO comments (content) values ('Received GET request on page')")

But I still get a 500 Internal Error:

2022-07-23 21:07:48,732: Exception on / [GET]
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/mysql/connector/connection_cext.py", line 504, in cmd_query
    self._cmysql.query(query,
AttributeError: 'NoneType' object has no attribute 'query'
**NO MATCH**
During handling of the above exception, another exception occurred:
**NO MATCH**
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2051, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1501, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1499, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1485, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "/home/pegasus163/mysite/flask_app.py", line 88, in index
    cursor.execute(message)
  File "/usr/local/lib/python3.7/site-packages/mysql/connector/cursor_cext.py", line 266, in execute
    raw_as_string=self._raw_as_string)
  File "/usr/local/lib/python3.7/site-packages/mysql/connector/connection_cext.py", line 516, in cmd_query
    errno=2055, values=(addr, 'Connection not available.'))
mysql.connector.errors.OperationalError: 2055: Lost connection to MySQL server at 'pegasus163.mysql.pythonanywhere-services.com:3306', system error: Connection not available.

I hope you still have the patience to help.

Since I CAN write to other tables, but not my Comment table with 1 column, I have created another table (Log) with 2 columns, into which I can log process actions. This works perfectly in the interface, but again, FAILS when serving POST calls.

2022-07-24 08:30:16,154: Exception on /TV-BIN [POST]
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/mysql/connector/connection_cext.py", line 506, in cmd_query
    raw_as_string=raw_as_string)
_mysql_connector.MySQLInterfaceError: MySQL server has gone away
**NO MATCH**
During handling of the above exception, another exception occurred:
**NO MATCH**
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2051, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1501, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1499, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1485, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "/home/pegasus163/mysite/flask_app.py", line 415, in webhook_TV_BIN
    cursor.execute(log_sql,val)
  File "/usr/local/lib/python3.7/site-packages/mysql/connector/cursor_cext.py", line 266, in execute
    raw_as_string=self._raw_as_string)
  File "/usr/local/lib/python3.7/site-packages/mysql/connector/connection_cext.py", line 509, in cmd_query
    sqlstate=exc.sqlstate)
mysql.connector.errors.DatabaseError: 2006 (HY000): MySQL server has gone away

Current code:

mysql> describe log;
+------------+---------------+------+-----+-------------------+----------------+
| Field      | Type          | Null | Key | Default           | Extra          |
+------------+---------------+------+-----+-------------------+----------------+
| id         | int(11)       | NO   | PRI | NULL              | auto_increment |
| source     | varchar(12)   | NO   |     | NULL              |                |
| entry      | varchar(4096) | YES  |     | NULL              |                |
| created_on | timestamp     | YES  |     | CURRENT_TIMESTAMP |                |
+------------+---------------+------+-----+-------------------+----------------+
4 rows in set (0.00 sec)

#establishing the connection
conn = mysql.connector.connect(
   user=DBconfig.username, password=DBconfig.password, host=DBconfig.hostname, database=DBconfig.databasename)

#Creating a cursor object using the cursor() method
cursor = conn.cursor()

# Prepare SQL query to INSERT a record into the balance table
log_sql     = "INSERT INTO log (source, entry) values (%s, %s)"

    source      = "BIN"
    message = str(now) + ' Placing BIN Order: ' + side + ' ' + str(qty) + ' ' + symbol + ' @ '+ str(price)
    val = (source, message)
    cursor.execute(log_sql,val)  # line triggering error

Why does the same code work in interactive mode, but not when serving POSTs? Please advise!

See our help page on managing connections: https://help.pythonanywhere.com/pages/ManagingDatabaseConnections/