How to insert unicode string to mysql - python

the code is like below:
Connect server
MySQLdb.connect(host=ip, user='root', passwd='root',db='test',use_unicode=True,charset="utf8")
......
sql = "INSERT INTO ci(id,name) VALUES (493,u'Hello')"
print sql
ret = root.execute(sql)
.....
In the server, the tyoe of name is VARCHAR(1000). Then when i run this script, it shows error ProgrammingError: (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
But when i replace u'Hello' with 'Hello', it is OK. So maybe it doesn't support unicode,then i insert unicode string such as "你好" to the table by GUI manually, it is also OK. I can not find what is the reason, who can help me

MySQL needs strings to be enclosed in straight quotes: '你好', 'u' symbol is not allowed. Just declare the whole string as Unicode and pass it to MySQL. Here I am using a prepared statement:
sql = u"INSERT INTO ci(id,name) VALUES (493,'你好')"
Don't forget to run "SET NAMES 'UTF-8'" (or UTF-16 - don't know, what encoding you are using) after you connect to MySQL to ensure, that the server will correctly interpret the string you send it.

Related

Create MariaDB database with Python

I would like to write a python script to create new MariaDB databases.
The database name is a user input. I tried to use arguments for creating the database:
#!/usr/bin/python3
import mysql.connector
mariadb_host = '127.0.0.1'
mariadb_port = 3306
mariadb_user = 'root'
mariadb_password = 'password'
mariadb_connection = mysql.connector.connect(
host=mariadb_host,
port=mariadb_port,
user=mariadb_user,
passwd=mariadb_password,
use_pure=True
)
query = 'CREATE DATABASE %(db_name)s;'
args = {'db_name': 'test-db'}
result = None
cursor = mariadb_connection.cursor()
cursor.execute(query, args)
print(cursor.statement)
result = cursor.fetchall()
cursor.close()
The following error appears: mysql.connector.errors.ProgrammingError: 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''test-db'' at line 1
It seems, that the command cursor.execute appends ' around the database name, which results in an invalid sql query.
How could I get around this problem and create safely new database from user input?
Parameter substitution notation - %(name)s or just %s is for interpolating values into an SQL statement.
RDBMSs have different quoting rules for values and identifiers like database, table or column names. For example, a string value will be surrounded by single quotes to tell the RDBMS that is is a character value, but single-quoting an identifier is a syntax error; the RDBMS will require that identifiers are quoted using some other character (for example backticks, double-quotes, square brackets, depending on the RDBMS).
If you want to interpolate identifiers using Python you have to use string formatting techniques. For example, using an f-string
db_name = 'test-db'
query = f'CREATE DATABASE `{db_name}`;'
Note that it is best to quote dynamic identifier names with backticks to handle names which contain special characters.
As always with dynamic SQL generation, you should be aware of the risk of SQL injection when handling data from an untrusted source.

python peewee raw query without escaping characters

Is there any way to prevent escaping backslash in python peewee (peewee-2.8.8) ORM?
I would like to execute query in MySQL database:
SHOW MASTER STATUS\G
The "\G" part is essential! I need to the results in vertical form.
The problem is that peewee always escapes backslash (\) so it ends in MySQL as:
SHOW MASTER STATUS\\G
and of course MySQL issues an error:
"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 '\\G' at line 1"
I tried to use plain "execute_sql" method:
cursor = RaDatabase.execute_sql('SHOW MASTER STATUS\G')
and also "raw" method:
query = BaseModel.raw('SHOW MASTER STATUS\G')
result = query.execute()
but both ended with escaping characters.
Have you tried using a "raw" string?
cursor = RaDatabase.execute_sql(r'SHOW MASTER STATUS\G')
For what it's worth, whatever you pass in to .execute_sql() is essentially handed over to the MySQL driver (pymysql, or whatever you're using). Peewee itself does not do any escaping.

SQL statement fails through mysqldb.query in Python

I am trying to pass a query through my script, but i get a SQL error.
Running the same sql statement in Heidisql works fine.
My question is:
- What am I doing wrong?
error message
_mysql.connection.query(self, query)
_mysql_exceptions.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server
version for the right syntax to use near 'Gabrielsen)' at line 1")
Python script where Database is the correct connection to database
F="Gunnar Gabrielsen"
Database.query('INSERT INTO documents (name) values (' + F + ');')
i=Database.query('SELECT * from documents;')
print(i)
Python version:Python 3.4
Module:Mysqldb
DB:MariaDB
You haven't put quotes around your value.
But you should never do it this way anyway. Quite apart from the quoting problem, you are opening yourself to sql injection attacks.
Use a parametrised query instead:
cursor.execute('INSERT INTO documents (name) values (%s)', (F,))
You have generated this:
INSERT INTO documents (name) values (Gunnar Gabrielsen);
What you need is
INSERT INTO documents (name) values ("Gunnar Gabrielsen");
But, without escaping or parameterizing, you are opening your code (and system) up to "sql injection" and other hacking.

psycopg2.ProgrammingError: syntax error at or near "\"

I have a python module which copy data from a table to a file.Im using postgresql as database server. COPY is the command is to be used to do the above action.
However in a blog (http://grokbase.com/t/postgresql/pgsql-general/058tagtped/about-error-must-be-superuser-to-copy-to-or-from-a-file) it states that, You can use \copy in 'psql' on the client side, but you have to be a superuser to do COPY on the server side, for security reasons. So I used \copy command. When I try to execute the below method, it results in error as
psycopg2.ProgrammingError: syntax error at or near "\" LINE 1: \copy
I can't find why its throwing error. can someone help me out?
def process():
query="\copy %s TO %s"%('test_table', 'test_file.txt')
#env.with_transaction()
def do_execute(db):
cursor = db.cursor()
cursor.execute(query)
do_execute is a database wrapper, which creates connection and
executes the query.
\ is an escape in Python strings, so your string contains the escape \c. However \c is an invalid escape in Python, and Python leaves invalid escapes unchanged, so "\copy" is just \copy. (Thus #tiziano's answer is misleading).
>>> print "\c"
\c
The real problem is that \copy is a psql command, not a server side PostgreSQL command. You can't use it with a client other than psql. You must instead use the psycopg2 support for COPY to do it via your client driver.

Prevent MySQL-Python from inserting quotes around database name parameter

I'm working on a project that requires me to programmatically create MySQL users from a django app. I can create the users just fine:
from django.db import connection, transaction
cursor = connection.cursor()
cursor.execute("CREATE USER %s#'%'", 'username')
cursor.execute("SET PASSWORD FOR %s#'%' = PASSWORD(%s)", ('username', 'pass'))
That works perfectly. The problem is when I try to grant permissions. The database name is also determined programmatically:
cursor.execute("GRANT SELECT ON %s.* TO %s#'%'", ('dbname', 'username'))
This results in a mysql error because when it does the string substitution, it places single quotes around the database name, which is syntactically incorrect:
DatabaseError: (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 ''dbname'.* to 'username'#'%'' at line 1")
How do I prevent the single quotes from being added around the %s for database name? I know that I could simply do the string substitution in Python and fix this, but that could potentially cause a SQL injection vulnerability.
Sometimes placeholders won't work (as you've found out), so you'll have to use string concatenation. Be careful - validate the string, make sure it's only composed of the characters you expect (don't just look for characters you don't expect), and you should be OK. Also get another developer to check your code, and comment it to make sure no-one else thinks you ought to be using placeholders.

Categories