Skip to content

Commit 9f5a64c

Browse files
author
Carl Sverre
committed
Release memsql-python 3.1.0
1 parent 28b9580 commit 9f5a64c

File tree

10 files changed

+57
-32
lines changed

10 files changed

+57
-32
lines changed

CHANGES.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
2020-04-25 Version 3.1.0
2+
3+
* Upgrade mysqlclient to 1.4 or greator
4+
15
2019-07-24 Version 3.0.0
26

37
* Remove Python 2 support

Makefile

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,25 @@ all:
22
rm -rf build/ dist; ./setup.py sdist
33

44
upload: all
5-
python setup.py sdist
5+
python3 setup.py sdist
66
twine upload dist/*
77

88
clean:
99
rm -rf *.egg memsql.egg-info dist build
10-
python setup.py clean --all
10+
python3 setup.py clean --all
1111
for _kill_path in $$(find . -type f -name "*.pyc"); do rm -f $$_kill_path; done
1212
for _kill_path in $$(find . -name "__pycache__"); do rm -rf $$_kill_path; done
1313

1414
test:
15-
python setup.py test
15+
python3 setup.py test
1616

1717
test-watch:
18-
python setup.py test -w
18+
python3 setup.py test -w
1919

2020
.PHONY: flake8
2121
flake8:
2222
flake8 --config=.flake8 .
2323

24-
.PHONY: shell-py2
25-
shell-py2:
26-
nix-shell -A memsqlPython2Env
27-
28-
.PHONY: shell-py3
29-
shell-py3:
30-
nix-shell -A memsqlPython3Env
24+
.PHONY: shell
25+
shell:
26+
nix-shell -A memsqlPython

memsql/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
""" MemSQL-python
22
"""
33

4-
__version__ = "3.0.0"
4+
__version__ = "3.1.0"

memsql/common/connection_pool.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import _mysql, errno
1+
from MySQLdb import _mysql
2+
import errno
23
import multiprocessing
34
import logging
45
from memsql.common import database

memsql/common/conversions.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
1-
import _mysql
21
from MySQLdb.constants import FIELD_TYPE
3-
from MySQLdb.converters import conversions
4-
from MySQLdb import times
2+
from MySQLdb.converters import conversions, Bool2Str
3+
from MySQLdb import times, _mysql
54
import datetime
5+
import inspect
66

77
CONVERSIONS = conversions
88

99
def _bytes_to_utf8(b):
1010
return b.decode('utf-8')
1111

12-
CONVERSIONS[FIELD_TYPE.STRING].append((None, _bytes_to_utf8))
13-
CONVERSIONS[FIELD_TYPE.VAR_STRING].append((None, _bytes_to_utf8))
14-
CONVERSIONS[FIELD_TYPE.VARCHAR].append((None, _bytes_to_utf8))
15-
CONVERSIONS[FIELD_TYPE.BLOB].append((None, _bytes_to_utf8))
12+
CONVERSIONS[FIELD_TYPE.STRING] = _bytes_to_utf8
13+
CONVERSIONS[FIELD_TYPE.VAR_STRING] = _bytes_to_utf8
14+
CONVERSIONS[FIELD_TYPE.VARCHAR] = _bytes_to_utf8
15+
CONVERSIONS[FIELD_TYPE.BLOB] = _bytes_to_utf8
1616

1717
def _escape_bytes(b, c):
1818
return _mysql.string_literal(b, c).decode('utf-8')
1919

2020
CONVERSIONS[bytes] = _escape_bytes
2121

2222
def _escape_string(s, d):
23-
return _mysql.string_literal(s.encode('utf-8'), d).decode('utf-8')
23+
return _mysql.string_literal(s.encode('utf-8')).decode('utf-8')
2424

2525
CONVERSIONS[str] = _escape_string
2626

@@ -31,3 +31,7 @@ def _escape_timedelta(dt, c):
3131

3232
CONVERSIONS[datetime.datetime] = _escape_datetime
3333
CONVERSIONS[datetime.timedelta] = _escape_timedelta
34+
35+
def _escape_bool(b, d):
36+
return Bool2Str(b, d).decode('utf-8')
37+
CONVERSIONS[bool] = _escape_bool

memsql/common/database.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""A lightweight wrapper around _mysql."""
22

3-
import _mysql
3+
from MySQLdb import _mysql
44
import time
55
import operator
66

@@ -301,7 +301,9 @@ def escape_query(query, parameters):
301301
return query
302302

303303
def _escape(param):
304+
_bytes_to_utf8 = lambda b: b.decode("utf-8") if isinstance(b, bytes) else b
305+
304306
if isinstance(param, (list, tuple)):
305-
return ','.join(_mysql.escape(p, CONVERSIONS) for p in param)
307+
return ','.join(_bytes_to_utf8(_mysql.escape(p, CONVERSIONS)) for p in param)
306308
else:
307-
return _mysql.escape(param, CONVERSIONS)
309+
return _bytes_to_utf8(_mysql.escape(param, CONVERSIONS))

memsql/common/test/test_connection_pool.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,14 +196,14 @@ def raise_ioerror(*args, **kwargs):
196196
assert (e.host, e.port, e.user, e.password, e.db_name, e.options, e.pid) == test_key
197197

198198
def test_sql_errors(fairy):
199-
from _mysql import ProgrammingError
199+
from MySQLdb._mysql import ProgrammingError
200200
with pytest.raises(ProgrammingError):
201201
fairy.query('asdf bad query!!')
202202

203203
def test_exception_remapping(pool, db_args, test_db_database):
204204
from memsql.common.connection_pool import PoolConnectionException
205205
from memsql.common import errorcodes
206-
import _mysql
206+
from MySQLdb import _mysql
207207

208208
# check that some operationalerrors get mapped to PoolConnectionException
209209
bad_db_args = db_args[:-1] + ("aasjdkfjdoes_not_exist",)

memsql/common/test/test_database_adapters.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
import pytest
44
import time
5-
from memsql.common import database
5+
from memsql.common import query_builder, database
66
import uuid
7+
import datetime
78
import copy
89

910
def test_connection_open(test_db_conn):
@@ -95,6 +96,23 @@ def test_insert(self, x_conn):
9596
last_row = x_conn.get('SELECT * FROM x ORDER BY id DESC LIMIT 1')
9697
assert res == last_row.id
9798

99+
def test_insert_qb(self, x_conn):
100+
rows = [
101+
{ 'id': 1, 'value': '2', 'col1': 1223.4, 'col2': datetime.datetime.now(), 'colb': True },
102+
{ 'id': 2, 'value': None, 'col1': None, 'col2': None, 'colb': None },
103+
]
104+
sql, params = query_builder.multi_insert('x', *rows)
105+
106+
res = x_conn.query(sql, **params)
107+
assert isinstance(res, int)
108+
assert res == 2 # 2 affected row
109+
110+
all_rows = x_conn.query('SELECT * FROM x ORDER BY id ASC')
111+
assert len(all_rows) == 2
112+
assert all_rows[0].value == 2
113+
assert all_rows[0].col1 == "1223.4"
114+
assert all_rows[1].value == None
115+
98116
def test_select(self, x_conn):
99117
x_conn.execute('INSERT INTO x (value) VALUES (1), (2), (3)')
100118

memsql/common/test/test_query_builder.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,25 @@ def test_simple_expression():
55
sql, params = query_builder.simple_expression(', ', **x)
66
assert sql == '`a`=%(_QB_a)s, `b`=%(_QB_b)s, `c`=%(_QB_c)s'
77
assert params == { '_QB_a': 1, '_QB_b': '2', '_QB_c': 1223.4 }
8-
assert database.escape_query(sql, params) == r"`a`=1, `b`='2', `c`=1223.4"
8+
assert database.escape_query(sql, params) == r"`a`=1, `b`='2', `c`=1223.4e0"
99

1010
def test_update():
1111
x = { 'a': 1, 'b': '2', 'c': 1223.4 }
1212
sql, params = query_builder.update('foo', **x)
1313
assert sql == 'UPDATE `foo` SET `a`=%(_QB_a)s, `b`=%(_QB_b)s, `c`=%(_QB_c)s'
1414
assert params == { '_QB_a': 1, '_QB_b': '2', '_QB_c': 1223.4 }
15-
assert database.escape_query(sql, params) == r"UPDATE `foo` SET `a`=1, `b`='2', `c`=1223.4"
15+
assert database.escape_query(sql, params) == r"UPDATE `foo` SET `a`=1, `b`='2', `c`=1223.4e0"
1616

1717
def test_multi_insert():
1818
rows = [{ 'a': 1, 'b': '2', 'c': 1223.4 }, { 'a': 2, 'b': '5', 'c': 1 }]
1919
sql, params = query_builder.multi_insert('foo', *rows)
2020
assert sql == 'INSERT INTO `foo` (`a`, `b`, `c`) VALUES (%(_QB_ROW_0)s), (%(_QB_ROW_1)s)'
2121
assert params == { '_QB_ROW_0': [1, '2', 1223.4], '_QB_ROW_1': [2, '5', 1] }
22-
assert database.escape_query(sql, params) == r"INSERT INTO `foo` (`a`, `b`, `c`) VALUES (1,'2',1223.4), (2,'5',1)"
22+
assert database.escape_query(sql, params) == r"INSERT INTO `foo` (`a`, `b`, `c`) VALUES (1,'2',1223.4e0), (2,'5',1)"
2323

2424
def test_replace():
2525
rows = [{ 'a': 1, 'b': '2', 'c': 1223.4 }, { 'a': 2, 'b': '5', 'c': 1 }]
2626
sql, params = query_builder.multi_replace('foo', *rows)
2727
assert sql == 'REPLACE INTO `foo` (`a`, `b`, `c`) VALUES (%(_QB_ROW_0)s), (%(_QB_ROW_1)s)'
2828
assert params == { '_QB_ROW_0': [1, '2', 1223.4], '_QB_ROW_1': [2, '5', 1] }
29-
assert database.escape_query(sql, params) == r"REPLACE INTO `foo` (`a`, `b`, `c`) VALUES (1,'2',1223.4), (2,'5',1)"
29+
assert database.escape_query(sql, params) == r"REPLACE INTO `foo` (`a`, `b`, `c`) VALUES (1,'2',1223.4e0), (2,'5',1)"

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
'wraptor',
1313
'simplejson',
1414
'python-dateutil<3.0',
15-
'mysqlclient==1.3.13',
15+
'mysqlclient>=1.4',
1616
]
1717

1818
class PyTest(TestCommand):

0 commit comments

Comments
 (0)