Coder Social home page Coder Social logo

blue-yonder / turbodbc Goto Github PK

View Code? Open in Web Editor NEW
604.0 31.0 85.0 1.82 MB

Turbodbc is a Python module to access relational databases via the Open Database Connectivity (ODBC) interface. The module complies with the Python Database API Specification 2.0.

Home Page: http://turbodbc.readthedocs.io/en/latest

License: MIT License

CMake 4.49% Shell 0.04% C++ 74.34% C 0.15% Python 17.99% Makefile 1.00% Batchfile 0.04% Earthly 1.95%
python odbc database exasol numpy data-science pep249 python-database-api pyodbc speedup

turbodbc's People

Contributors

adament avatar alippai avatar amerkel2 avatar atombaf avatar bjoern-meier-by avatar bjoernmeier avatar chmp avatar cshaley avatar david-engelmann avatar dependabot[bot] avatar dvska avatar fjetter avatar gblivegblive avatar h-vetinari avatar holgerpeters avatar jmao-denver avatar keitherskine avatar kszucs avatar ldacey avatar mariusvniekerk avatar mathmagique avatar matthias-bach-by avatar nicoretti avatar pacman82 avatar rupurt avatar simeonstoykovqc avatar smithcre avatar wesm avatar xhochy avatar yaxxie avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

turbodbc's Issues

High memory usage with MSSQL ntext

I see sometimes see very high memory consumption when selecting from SQL Server ntext columns.
I think it might be triggered when the tables are empty.

The script below was run on Ubuntu 16.04 with turbodbc 1.1.0 and mssql-server 14.0.405.200-1.
massif output shows an heap allocation of 2GB, turning on use_async_io doubles the usage to 4GB.

The memory usage starts at snapshot 63, so I am not use if the stack trace in snapshot 64 is relevant.
(massif-visualizer is useful for visualizing)

from turbodbc import connect
conn = connect(DRIVER="ODBC Driver 13 for SQL Server",SERVER="localhost",DATABASE="test_db",UID="SA",PWD="password")
curs = conn.cursor()

curs.execute("""IF OBJECT_ID('mytable', 'U') IS NOT NULL 
                DROP TABLE [mytable]""")

curs.execute("""CREATE TABLE mytable(
	            foo ntext
                )""")

curs.execute("SELECT * FROM mytable")
valgrind --tool=massif python createmytable.py
#-----------
snapshot=62
#-----------
time=63680421
mem_heap_B=1951776
mem_heap_extra_B=74400
mem_stacks_B=0
heap_tree=empty
#-----------
snapshot=63
#-----------
time=298830808
mem_heap_B=2149397260
mem_heap_extra_B=78044
mem_stacks_B=0
heap_tree=empty
#-----------
snapshot=64
#-----------
time=298844168
mem_heap_B=2149401564
mem_heap_extra_B=78108
mem_stacks_B=0
heap_tree=peak
n2: 2149401564 (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
 n1: 2147483648 0x69C6911: cpp_odbc::multi_value_buffer::multi_value_buffer(unsigned long, unsigned long) (new_allocator.h:104)
  n1: 2147483648 0x69CFE23: turbodbc::column::column(cpp_odbc::statement const&, unsigned long, unsigned long, std::unique_ptr<turbodbc::description const, std::default_delete<turbodbc::description const> >) (column.cpp:9)
   n1: 2147483648 0x69D5EB2: void std::vector<turbodbc::column, std::allocator<turbodbc::column> >::_M_emplace_back_aux<cpp_odbc::statement const&, unsigned long&, unsigned long&, std::unique_ptr<turbodbc::description const, std::default_delete<turbodbc::description const> > >(cpp_odbc::statement const&, unsigned long&, unsigned long&, std::unique_ptr<turbodbc::description const, std::default_delete<turbodbc::description const> >&&) (new_allocator.h:120)
    n1: 2147483648 0x69D5991: turbodbc::result_sets::bound_result_set::bound_result_set(std::shared_ptr<cpp_odbc::statement const>, boost::variant<turbodbc::rows, turbodbc::megabytes>, bool) (vector.tcc:101)
     n1: 2147483648 0x69CE8CD: turbodbc::command::execute() (new_allocator.h:120)
      n1: 2147483648 0x69CD072: turbodbc::cursor::execute() (cursor.cpp:58)
       n1: 2147483648 0x67852F3: void pybind11::cpp_function::initialize<pybind11::cpp_function::initialize<void, turbodbc::cursor, , pybind11::name, pybind11::is_method, pybind11::sibling>(void (turbodbc::cursor::*)(), pybind11::name const&, pybind11::is_method const&, pybind11::sibling const&)::{lambda(turbodbc::cursor*)#1}, void, turbodbc::cursor*, pybind11::name, pybind11::is_method, pybind11::sibling>(pybind11::cpp_function::initialize<void, turbodbc::cursor, , pybind11::name, pybind11::is_method, pybind11::sibling>(void (turbodbc::cursor::*)(), pybind11::name const&, pybind11::is_method const&, pybind11::sibling const&)::{lambda(turbodbc::cursor*)#1}&&, void (*)(turbodbc::cursor*), pybind11::name const&, pybind11::is_method const&, pybind11::sibling const&)::{lambda(pybind11::detail::function_record*, pybind11::handle, pybind11::detail::function_record*, pybind11::detail::function_record*)#3}::_FUN(pybind11::detail::function_record, pybind11::detail::function_record*, pybind11::detail::function_record*, pybind11::detail::function_record*) (pybind11.h:62)
        n1: 2147483648 0x677F025: pybind11::cpp_function::dispatcher(_object*, _object*, _object*) (pybind11.h:441)
         n1: 2147483648 0x4CADA0: PyEval_EvalFrameEx (in /usr/bin/python2.7)
          n1: 2147483648 0x4C2763: PyEval_EvalCodeEx (in /usr/bin/python2.7)
           n1: 2147483648 0x4DE8B6: ??? (in /usr/bin/python2.7)
            n1: 2147483648 0x4B0CB1: PyObject_Call (in /usr/bin/python2.7)
             n1: 2147483648 0x4C6ACF: PyEval_EvalFrameEx (in /usr/bin/python2.7)
              n1: 2147483648 0x4C2763: PyEval_EvalCodeEx (in /usr/bin/python2.7)
               n1: 2147483648 0x4CA8CF: PyEval_EvalFrameEx (in /usr/bin/python2.7)
                n1: 2147483648 0x4C2763: PyEval_EvalCodeEx (in /usr/bin/python2.7)
                 n1: 2147483648 0x4C2507: PyEval_EvalCode (in /usr/bin/python2.7)
                  n1: 2147483648 0x4F1DED: ??? (in /usr/bin/python2.7)
                   n1: 2147483648 0x4EC650: PyRun_FileExFlags (in /usr/bin/python2.7)
                    n1: 2147483648 0x4EAE2F: PyRun_SimpleFileExFlags (in /usr/bin/python2.7)
                     n1: 2147483648 0x49E148: Py_Main (in /usr/bin/python2.7)
                      n0: 2147483648 0x506E82E: (below main) (libc-start.c:291)
 n0: 1917916 in 361 places, all below massif's threshold (1.00%)
#-----------
snapshot=65
#-----------
time=300787456
mem_heap_B=2149388856
mem_heap_extra_B=78032
mem_stacks_B=0
heap_tree=empty
#-----------

Failure on parameter discovery in the presence of column functions

$ pip freeze | grep turbo
turbodbc==1.0.2

I have a result set 'rows' that has come from an Oracle cusror/fetchall

Some of the columns are Oracle VARCHAR2 types, which need to have the empty string. As we know, Oracle can't store the empty string in VARCHAR2, so these columns are coming back as NULL (None in the tuple) and my SQL Server database column is NOT NULL (expecting empty string).

I tried to put COALESCE in my SQL Server insert, but I get the following error:

mscursor.executemany(stmt, rows)

stmt is:
insert into TAEMENUL ( MENU, SEQ, LINE_MENU, PRG, DESCR, DFLTS, URL, EXE, LINE_MODULE_CODES ) values( ? ,  ? ,  ? ,  ? ,  ? ,  ? , coalesce( ? ,''), coalesce( ? ,''),  ? )

result:
MS insert Error ODBC error
state: 42000
native error code: 11502
message: [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]The type for parameter '@P7' cannot be deduced in this context.

So this shows my INSERT statement with placeholders, and the two placeholders within the COALESCE functions.

This worked when I used pymssql , but was much too slow, hence coming to turbodbc (my migration program now runs in 12 minutes, instead of 3 hours)

But, how can I get this to work in turbodbc to convert the NULLs to empty string?

Problems with SQL Server timestamps on Windows

I am using this snippet for testing on Windows with the "SQL Server" driver.

now = datetime.datetime.now().replace(microsecond=0)
curs.execute("select ?", [now])

The default value for timestamp digits of 6 complains about Invalid scale value.
In a MSSQL example MAXIMUM_SCALE is 3, and using this value stops the complaining about Invalid scale value.
Instead it starts complaining about Datetime field overflow.

From what i can tell the turbodbc element size is the same as the ODBC Column Size. The size of this should according to the link not be the size of the struct, but the length of an arbitrary string representation of the datetime. In the MSSQL example COLUMN_SIZE is 23. Using this value for element size gets rid of "Datetime field overflow", and the example works.

However, when using microseconds, the Datetime field overflow comes back.

now = datetime.datetime.now().replace(microsecond=1)
curs.execute("select ?", [now])

However when microsecond is a multiple of 1000, it works.

now = datetime.datetime.now().replace(microsecond=1000)
curs.execute("select ?", [now])

Error inserting boolean values into MySQL 5.7's BIT fields

When using a MySQL 5.7 database and a table with a column of type BIT, the following error message occurs when inserting a boolean value:

DatabaseError: ODBC error
state: HY000
native error code: 1406
message: [MySQL][ODBC 5.3(a) Driver][mysqld-5.7.17-0ubuntu0.16.04.1]Data too long for column 'a' at row 1

Request for auto commit option on the connection

I just wanted to add this issue as a placeholder for an "auto commit" option. It would be very handy to have an option on the connect function to tell the database to commit after every SQL statement (i.e. by setting SQL_ATTR_AUTOCOMMIT). This would save users from having to explicitly call commit() after every call to execute. The default would be not to implicitly commit, to comply with PEP249, but it would be good to be able to set this attribute when needed. Better still it would be good to be able to change this attribute dynamically, e.g. switch on "auto-commit" on the connection after the connection is established and then switch it off again later, all without dropping the connection. I appreciate this attribute and behaviour may not be supported by all RDBMS's, but this is possible and does work with MS SQL Server.

For examples of existing implementations, see pyodbc and MySQL.

Official Windows support

To bring the Windows support from an experimental state to a production-ready one, a continuous build with passing integration tests is required. Also, a binary build would be well received since compiling on Windows is a little less straight-forward than desirable.

Cannot pip wheel turbodbc with numpy 1.8.0 through numpy 1.9.2

I tried to build turbodbc with numpy 1.8.0 using pip wheel.

Reproducing Steps

On Debian 7:

virtualenv venv
pip install numpy==1.8.0
pip wheel turbodbc

It seems to work with numpy==1.10.1 and (I suspect) above.

Context

gcc version is 4.7.2, python version is 2.7.3

Error

Building wheels for collected packages: turbodbc
  Running setup.py bdist_wheel for turbodbc ... error
  Complete output from command /tmp/turbodbc/venv/bin/python -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-QP3m6m/turbodbc/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" bdist_wheel -d /tmp/tmpaaSi1Ypip-wheel-:
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build/lib.linux-x86_64-2.7
  creating build/lib.linux-x86_64-2.7/turbodbc
  copying turbodbc/api_constants.py -> build/lib.linux-x86_64-2.7/turbodbc
  copying turbodbc/connect.py -> build/lib.linux-x86_64-2.7/turbodbc
  copying turbodbc/constructors.py -> build/lib.linux-x86_64-2.7/turbodbc
  copying turbodbc/cursor.py -> build/lib.linux-x86_64-2.7/turbodbc
  copying turbodbc/exceptions.py -> build/lib.linux-x86_64-2.7/turbodbc
  copying turbodbc/data_types.py -> build/lib.linux-x86_64-2.7/turbodbc
  copying turbodbc/connection.py -> build/lib.linux-x86_64-2.7/turbodbc
  copying turbodbc/__init__.py -> build/lib.linux-x86_64-2.7/turbodbc
  running egg_info
  writing turbodbc.egg-info/PKG-INFO
  writing top-level names to turbodbc.egg-info/top_level.txt
  writing dependency_links to turbodbc.egg-info/dependency_links.txt
  reading manifest file 'turbodbc.egg-info/SOURCES.txt'
  reading manifest template 'MANIFEST.in'
  writing manifest file 'turbodbc.egg-info/SOURCES.txt'
  running build_ext
  building 'libturbodbc' extension
  creating build/temp.linux-x86_64-2.7
  creating build/temp.linux-x86_64-2.7/src
  creating build/temp.linux-x86_64-2.7/src/cpp_odbc
  creating build/temp.linux-x86_64-2.7/src/cpp_odbc/level1
  creating build/temp.linux-x86_64-2.7/src/cpp_odbc/level3
  creating build/temp.linux-x86_64-2.7/src/cpp_odbc/level2
  creating build/temp.linux-x86_64-2.7/src/turbodbc
  creating build/temp.linux-x86_64-2.7/src/turbodbc/result_sets
  creating build/temp.linux-x86_64-2.7/src/turbodbc/parameter_sets
  creating build/temp.linux-x86_64-2.7/src/turbodbc/field_translators
  creating build/temp.linux-x86_64-2.7/src/turbodbc/descriptions
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/cpp_odbc/connection.cpp -o build/temp.linux-x86_64-2.7/src/cpp_odbc/connection.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/cpp_odbc/make_environment.cpp -o build/temp.linux-x86_64-2.7/src/cpp_odbc/make_environment.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/cpp_odbc/multi_value_buffer.cpp -o build/temp.linux-x86_64-2.7/src/cpp_odbc/multi_value_buffer.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/cpp_odbc/environment.cpp -o build/temp.linux-x86_64-2.7/src/cpp_odbc/environment.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/cpp_odbc/error.cpp -o build/temp.linux-x86_64-2.7/src/cpp_odbc/error.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/cpp_odbc/statement.cpp -o build/temp.linux-x86_64-2.7/src/cpp_odbc/statement.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/cpp_odbc/cpp_odbc.cpp -o build/temp.linux-x86_64-2.7/src/cpp_odbc/cpp_odbc.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/cpp_odbc/column_description.cpp -o build/temp.linux-x86_64-2.7/src/cpp_odbc/column_description.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/cpp_odbc/level1/level1.cpp -o build/temp.linux-x86_64-2.7/src/cpp_odbc/level1/level1.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/cpp_odbc/level1/api.cpp -o build/temp.linux-x86_64-2.7/src/cpp_odbc/level1/api.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/cpp_odbc/level1/unixodbc_backend_debug.cpp -o build/temp.linux-x86_64-2.7/src/cpp_odbc/level1/unixodbc_backend_debug.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/cpp_odbc/level1/unixodbc_backend.cpp -o build/temp.linux-x86_64-2.7/src/cpp_odbc/level1/unixodbc_backend.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/cpp_odbc/level3/raii_environment.cpp -o build/temp.linux-x86_64-2.7/src/cpp_odbc/level3/raii_environment.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/cpp_odbc/level3/raii_connection.cpp -o build/temp.linux-x86_64-2.7/src/cpp_odbc/level3/raii_connection.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/cpp_odbc/level3/level3.cpp -o build/temp.linux-x86_64-2.7/src/cpp_odbc/level3/level3.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/cpp_odbc/level3/raii_statement.cpp -o build/temp.linux-x86_64-2.7/src/cpp_odbc/level3/raii_statement.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/cpp_odbc/level2/api.cpp -o build/temp.linux-x86_64-2.7/src/cpp_odbc/level2/api.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/cpp_odbc/level2/handles.cpp -o build/temp.linux-x86_64-2.7/src/cpp_odbc/level2/handles.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/cpp_odbc/level2/input_string_buffer.cpp -o build/temp.linux-x86_64-2.7/src/cpp_odbc/level2/input_string_buffer.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/cpp_odbc/level2/level2.cpp -o build/temp.linux-x86_64-2.7/src/cpp_odbc/level2/level2.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/cpp_odbc/level2/string_buffer.cpp -o build/temp.linux-x86_64-2.7/src/cpp_odbc/level2/string_buffer.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/cpp_odbc/level2/level1_connector.cpp -o build/temp.linux-x86_64-2.7/src/cpp_odbc/level2/level1_connector.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/connection.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/connection.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/make_field_translator.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/make_field_translator.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/buffer_size.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/buffer_size.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/command.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/command.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/description.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/description.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/cursor.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/cursor.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/make_description.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/make_description.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/column.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/column.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/connect.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/connect.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/field_translator.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/field_translator.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/parameter.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/parameter.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/result_sets/python_result_set.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/result_sets/python_result_set.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/result_sets/field_result_set.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/result_sets/field_result_set.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/result_sets/double_buffered_result_set.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/result_sets/double_buffered_result_set.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/result_sets/row_based_result_set.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/result_sets/row_based_result_set.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/result_sets/bound_result_set.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/result_sets/bound_result_set.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/result_sets/result_set.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/result_sets/result_set.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/parameter_sets/set_field.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/parameter_sets/set_field.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/parameter_sets/field_parameter_set.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/parameter_sets/field_parameter_set.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/parameter_sets/bound_parameter_set.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/parameter_sets/bound_parameter_set.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/field_translators/timestamp_translator.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/field_translators/timestamp_translator.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/field_translators/string_translator.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/field_translators/string_translator.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/field_translators/int64_translator.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/field_translators/int64_translator.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/field_translators/boolean_translator.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/field_translators/boolean_translator.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/field_translators/date_translator.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/field_translators/date_translator.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/field_translators/float64_translator.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/field_translators/float64_translator.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/descriptions/boolean_description.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/descriptions/boolean_description.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/descriptions/date_description.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/descriptions/date_description.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/descriptions/timestamp_description.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/descriptions/timestamp_description.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/descriptions/floating_point_description.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/descriptions/floating_point_description.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/descriptions/string_description.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/descriptions/string_description.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc/descriptions/integer_description.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc/descriptions/integer_description.o --std=c++11
  g++ -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-z,relro build/temp.linux-x86_64-2.7/src/cpp_odbc/connection.o build/temp.linux-x86_64-2.7/src/cpp_odbc/make_environment.o build/temp.linux-x86_64-2.7/src/cpp_odbc/multi_value_buffer.o build/temp.linux-x86_64-2.7/src/cpp_odbc/environment.o build/temp.linux-x86_64-2.7/src/cpp_odbc/error.o build/temp.linux-x86_64-2.7/src/cpp_odbc/statement.o build/temp.linux-x86_64-2.7/src/cpp_odbc/cpp_odbc.o build/temp.linux-x86_64-2.7/src/cpp_odbc/column_description.o build/temp.linux-x86_64-2.7/src/cpp_odbc/level1/level1.o build/temp.linux-x86_64-2.7/src/cpp_odbc/level1/api.o build/temp.linux-x86_64-2.7/src/cpp_odbc/level1/unixodbc_backend_debug.o build/temp.linux-x86_64-2.7/src/cpp_odbc/level1/unixodbc_backend.o build/temp.linux-x86_64-2.7/src/cpp_odbc/level3/raii_environment.o build/temp.linux-x86_64-2.7/src/cpp_odbc/level3/raii_connection.o build/temp.linux-x86_64-2.7/src/cpp_odbc/level3/level3.o build/temp.linux-x86_64-2.7/src/cpp_odbc/level3/raii_statement.o build/temp.linux-x86_64-2.7/src/cpp_odbc/level2/api.o build/temp.linux-x86_64-2.7/src/cpp_odbc/level2/handles.o build/temp.linux-x86_64-2.7/src/cpp_odbc/level2/input_string_buffer.o build/temp.linux-x86_64-2.7/src/cpp_odbc/level2/level2.o build/temp.linux-x86_64-2.7/src/cpp_odbc/level2/string_buffer.o build/temp.linux-x86_64-2.7/src/cpp_odbc/level2/level1_connector.o build/temp.linux-x86_64-2.7/src/turbodbc/connection.o build/temp.linux-x86_64-2.7/src/turbodbc/make_field_translator.o build/temp.linux-x86_64-2.7/src/turbodbc/buffer_size.o build/temp.linux-x86_64-2.7/src/turbodbc/command.o build/temp.linux-x86_64-2.7/src/turbodbc/description.o build/temp.linux-x86_64-2.7/src/turbodbc/cursor.o build/temp.linux-x86_64-2.7/src/turbodbc/make_description.o build/temp.linux-x86_64-2.7/src/turbodbc/column.o build/temp.linux-x86_64-2.7/src/turbodbc/connect.o build/temp.linux-x86_64-2.7/src/turbodbc/field_translator.o build/temp.linux-x86_64-2.7/src/turbodbc/parameter.o build/temp.linux-x86_64-2.7/src/turbodbc/result_sets/python_result_set.o build/temp.linux-x86_64-2.7/src/turbodbc/result_sets/field_result_set.o build/temp.linux-x86_64-2.7/src/turbodbc/result_sets/double_buffered_result_set.o build/temp.linux-x86_64-2.7/src/turbodbc/result_sets/row_based_result_set.o build/temp.linux-x86_64-2.7/src/turbodbc/result_sets/bound_result_set.o build/temp.linux-x86_64-2.7/src/turbodbc/result_sets/result_set.o build/temp.linux-x86_64-2.7/src/turbodbc/parameter_sets/set_field.o build/temp.linux-x86_64-2.7/src/turbodbc/parameter_sets/field_parameter_set.o build/temp.linux-x86_64-2.7/src/turbodbc/parameter_sets/bound_parameter_set.o build/temp.linux-x86_64-2.7/src/turbodbc/field_translators/timestamp_translator.o build/temp.linux-x86_64-2.7/src/turbodbc/field_translators/string_translator.o build/temp.linux-x86_64-2.7/src/turbodbc/field_translators/int64_translator.o build/temp.linux-x86_64-2.7/src/turbodbc/field_translators/boolean_translator.o build/temp.linux-x86_64-2.7/src/turbodbc/field_translators/date_translator.o build/temp.linux-x86_64-2.7/src/turbodbc/field_translators/float64_translator.o build/temp.linux-x86_64-2.7/src/turbodbc/descriptions/boolean_description.o build/temp.linux-x86_64-2.7/src/turbodbc/descriptions/date_description.o build/temp.linux-x86_64-2.7/src/turbodbc/descriptions/timestamp_description.o build/temp.linux-x86_64-2.7/src/turbodbc/descriptions/floating_point_description.o build/temp.linux-x86_64-2.7/src/turbodbc/descriptions/string_description.o build/temp.linux-x86_64-2.7/src/turbodbc/descriptions/integer_description.o -lodbc -lboost_python -o build/lib.linux-x86_64-2.7/libturbodbc.so
  building 'turbodbc_intern' extension
  creating build/temp.linux-x86_64-2.7/src/turbodbc_python
  creating build/temp.linux-x86_64-2.7/src/turbodbc_python/python_bindings
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc_python/determine_parameter_type.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc_python/determine_parameter_type.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc_python/python_parameter_set.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc_python/python_parameter_set.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc_python/python_bindings/connection.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc_python/python_bindings/connection.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc_python/python_bindings/python_result_set.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc_python/python_bindings/python_result_set.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc_python/python_bindings/column_info.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc_python/python_bindings/column_info.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc_python/python_bindings/buffer_size.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc_python/python_bindings/buffer_size.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc_python/python_bindings/unicode.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc_python/python_bindings/unicode.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc_python/python_bindings/error.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc_python/python_bindings/error.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc_python/python_bindings/cursor.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc_python/python_bindings/cursor.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc_python/python_bindings/python_parameter_set.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc_python/python_bindings/python_parameter_set.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc_python/python_bindings/connect.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc_python/python_bindings/connect.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/usr/include/python2.7 -c src/turbodbc_python/python_bindings/module.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc_python/python_bindings/module.o --std=c++11
  g++ -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-z,relro build/temp.linux-x86_64-2.7/src/turbodbc_python/determine_parameter_type.o build/temp.linux-x86_64-2.7/src/turbodbc_python/python_parameter_set.o build/temp.linux-x86_64-2.7/src/turbodbc_python/python_bindings/connection.o build/temp.linux-x86_64-2.7/src/turbodbc_python/python_bindings/python_result_set.o build/temp.linux-x86_64-2.7/src/turbodbc_python/python_bindings/column_info.o build/temp.linux-x86_64-2.7/src/turbodbc_python/python_bindings/buffer_size.o build/temp.linux-x86_64-2.7/src/turbodbc_python/python_bindings/unicode.o build/temp.linux-x86_64-2.7/src/turbodbc_python/python_bindings/error.o build/temp.linux-x86_64-2.7/src/turbodbc_python/python_bindings/cursor.o build/temp.linux-x86_64-2.7/src/turbodbc_python/python_bindings/python_parameter_set.o build/temp.linux-x86_64-2.7/src/turbodbc_python/python_bindings/connect.o build/temp.linux-x86_64-2.7/src/turbodbc_python/python_bindings/module.o -Lbuild/lib.linux-x86_64-2.7 -lodbc -lboost_python -lturbodbc -o build/lib.linux-x86_64-2.7/turbodbc_intern.so -Wl,-rpath,$ORIGIN
  building 'turbodbc_numpy_support' extension
  creating build/temp.linux-x86_64-2.7/src/turbodbc_numpy
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include -I/usr/include/python2.7 -c src/turbodbc_numpy/python_bindings.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc_numpy/python_bindings.o --std=c++11
  gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -Iinclude/ -I/tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include -I/usr/include/python2.7 -c src/turbodbc_numpy/string_column.cpp -o build/temp.linux-x86_64-2.7/src/turbodbc_numpy/string_column.o --std=c++11
  In file included from /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:4:0,
                   from /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:17,
                   from include/turbodbc_numpy/ndarrayobject.h:13,
                   from include/turbodbc_numpy/masked_column.h:3,
                   from include/turbodbc_numpy/string_column.h:3,
                   from src/turbodbc_numpy/string_column.cpp:1:
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/npy_common.h:301:2: error: #error Must use Python with unicode enabled.
  In file included from /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:4:0,
                   from /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:17,
                   from include/turbodbc_numpy/ndarrayobject.h:13,
                   from include/turbodbc_numpy/masked_column.h:3,
                   from include/turbodbc_numpy/string_column.h:3,
                   from src/turbodbc_numpy/string_column.cpp:1:
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/npy_common.h:164:9: error: โ€˜Py_intptr_tโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/npy_common.h:165:9: error: โ€˜Py_uintptr_tโ€™ does not name a type
  In file included from /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:4:0,
                   from /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:17,
                   from include/turbodbc_numpy/ndarrayobject.h:13,
                   from include/turbodbc_numpy/masked_column.h:3,
                   from include/turbodbc_numpy/string_column.h:3,
                   from src/turbodbc_numpy/string_column.cpp:1:
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/npy_common.h:949:9: error: โ€˜npy_uint16โ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/npy_common.h:950:9: error: โ€˜npy_halfโ€™ does not name a type
  In file included from /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:17:0,
                   from include/turbodbc_numpy/ndarrayobject.h:13,
                   from include/turbodbc_numpy/masked_column.h:3,
                   from include/turbodbc_numpy/string_column.h:3,
                   from src/turbodbc_numpy/string_column.cpp:1:
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:363:9: error: โ€˜PyObjectโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:364:35: error: typedef โ€˜PyArray_SetItemFuncโ€™ is initialized (use decltype instead)
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:364:35: error: โ€˜PyObjectโ€™ was not declared in this scope
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:364:45: error: expected primary-expression before โ€˜,โ€™ token
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:364:47: error: expected primary-expression before โ€˜voidโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:364:55: error: expected primary-expression before โ€˜voidโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:366:46: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:366:64: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:367:38: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:379:38: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:379:48: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:381:40: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:381:58: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:382:32: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:384:56: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:391:32: error: typedef โ€˜PyArray_ScanFuncโ€™ is initialized (use decltype instead)
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:391:32: error: โ€˜FILEโ€™ was not declared in this scope
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:391:38: error: โ€˜fpโ€™ was not declared in this scope
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:391:42: error: expected primary-expression before โ€˜voidโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:392:32: error: expected primary-expression before โ€˜charโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:392:46: error: expected primary-expression before โ€˜structโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:396:40: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:398:40: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:399:43: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:399:55: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:400:45: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:400:55: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:401:37: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:401:49: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:403:48: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:403:60: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:403:70: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:404:40: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:404:52: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:407:50: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:411:47: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:413:62: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:414:54: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:415:60: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:416:40: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:416:60: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:417:40: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:417:59: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:421:9: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:440:9: error: โ€˜PyArray_GetItemFuncโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:441:9: error: โ€˜PyArray_SetItemFuncโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:473:9: error: โ€˜PyArray_ScanFuncโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:513:9: error: โ€˜PyObjectโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:573:9: error: โ€˜PyObject_HEADโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:609:9: error: โ€˜PyObjectโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:614:9: error: โ€˜PyObjectโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:621:9: error: โ€˜PyObjectโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:632:9: error: โ€˜PyObjectโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:647:5: error: โ€˜PyObject_HEADโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:653:5: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:658:5: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:677:5: error: โ€˜PyObjectโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:683:5: error: โ€˜PyObjectโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:699:9: error: โ€˜PyObject_HEADโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:707:9: error: โ€˜PyObject_HEADโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:715:9: error: โ€˜PyObject_HEADโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:718:9: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:738:9: error: โ€˜npy_int32โ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:744:9: error: โ€˜npy_int32โ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:747:53: error: โ€˜PyObjectโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:976:39: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1053:66: error: โ€˜npy_intpโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1056:9: error: โ€˜PyObject_HEADโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1058:9: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1059:9: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1060:9: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1061:9: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1062:9: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1063:9: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1068:9: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1069:9: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1070:9: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1208:9: error: โ€˜PyObject_HEADโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1210:9: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1211:9: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1213:9: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1266:9: error: โ€˜PyObject_HEADโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1274:9: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1276:9: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1278:9: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1297:9: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1310:9: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1320:9: error: โ€˜npy_uint32โ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1331:9: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1339:9: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1342:9: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1355:5: error: โ€˜PyObject_HEADโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1361:5: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1362:5: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1363:5: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1364:5: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1365:5: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1366:5: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1371:5: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1372:5: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1373:5: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1379:5: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1382:5: error: โ€˜npy_intpโ€™ does not name a type
  In file included from /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1417:0,
                   from /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:17,
                   from include/turbodbc_numpy/ndarrayobject.h:13,
                   from include/turbodbc_numpy/masked_column.h:3,
                   from include/turbodbc_numpy/string_column.h:3,
                   from src/turbodbc_numpy/string_column.cpp:1:
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h: In function โ€˜int _PyArrayNeighborhoodIter_IncrCoord(PyArrayNeighborhoodIterObject*)โ€™:
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:40:5: error: โ€˜npy_intpโ€™ was not declared in this scope
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:40:14: error: expected โ€˜;โ€™ before โ€˜iโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:42:10: error: โ€˜iโ€™ was not declared in this scope
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:42:20: error: โ€˜struct PyArrayNeighborhoodIterObjectโ€™ has no member named โ€˜ndโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:43:9: error: โ€˜wbโ€™ was not declared in this scope
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:43:9: error: โ€˜struct PyArrayNeighborhoodIterObjectโ€™ has no member named โ€˜coordinatesโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:43:9: error: โ€˜struct PyArrayNeighborhoodIterObjectโ€™ has no member named โ€˜boundsโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:43:9: error: โ€˜struct PyArrayNeighborhoodIterObjectโ€™ has no member named โ€˜coordinatesโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:43:9: error: โ€˜struct PyArrayNeighborhoodIterObjectโ€™ has no member named โ€˜coordinatesโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:43:9: error: โ€˜struct PyArrayNeighborhoodIterObjectโ€™ has no member named โ€˜boundsโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h: In function โ€˜int _PyArrayNeighborhoodIter_IncrCoord2D(PyArrayNeighborhoodIterObject*)โ€™:
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:55:5: error: โ€˜npy_intpโ€™ was not declared in this scope
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:55:14: error: expected โ€˜;โ€™ before โ€˜wbโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:57:5: error: โ€˜wbโ€™ was not declared in this scope
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:57:5: error: โ€˜struct PyArrayNeighborhoodIterObjectโ€™ has no member named โ€˜coordinatesโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:57:5: error: โ€˜struct PyArrayNeighborhoodIterObjectโ€™ has no member named โ€˜boundsโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:57:5: error: โ€˜struct PyArrayNeighborhoodIterObjectโ€™ has no member named โ€˜coordinatesโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:57:5: error: โ€˜struct PyArrayNeighborhoodIterObjectโ€™ has no member named โ€˜coordinatesโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:57:5: error: โ€˜struct PyArrayNeighborhoodIterObjectโ€™ has no member named โ€˜boundsโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:58:5: error: โ€˜struct PyArrayNeighborhoodIterObjectโ€™ has no member named โ€˜coordinatesโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:58:5: error: โ€˜struct PyArrayNeighborhoodIterObjectโ€™ has no member named โ€˜boundsโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:58:5: error: โ€˜struct PyArrayNeighborhoodIterObjectโ€™ has no member named โ€˜coordinatesโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:58:5: error: โ€˜struct PyArrayNeighborhoodIterObjectโ€™ has no member named โ€˜coordinatesโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:58:5: error: โ€˜struct PyArrayNeighborhoodIterObjectโ€™ has no member named โ€˜boundsโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h: In function โ€˜int PyArrayNeighborhoodIter_Next(PyArrayNeighborhoodIterObject*)โ€™:
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:71:69: error: โ€˜struct PyArrayNeighborhoodIterObjectโ€™ has no member named โ€˜coordinatesโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h: In function โ€˜int PyArrayNeighborhoodIter_Reset(PyArrayNeighborhoodIterObject*)โ€™:
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:82:5: error: โ€˜npy_intpโ€™ was not declared in this scope
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:82:14: error: expected โ€˜;โ€™ before โ€˜iโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:84:10: error: โ€˜iโ€™ was not declared in this scope
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:84:27: error: โ€˜struct PyArrayNeighborhoodIterObjectโ€™ has no member named โ€˜ndโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:85:15: error: โ€˜struct PyArrayNeighborhoodIterObjectโ€™ has no member named โ€˜coordinatesโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:85:38: error: โ€˜struct PyArrayNeighborhoodIterObjectโ€™ has no member named โ€˜boundsโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h:87:69: error: โ€˜struct PyArrayNeighborhoodIterObjectโ€™ has no member named โ€˜coordinatesโ€™
  In file included from /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:17:0,
                   from include/turbodbc_numpy/ndarrayobject.h:13,
                   from include/turbodbc_numpy/masked_column.h:3,
                   from include/turbodbc_numpy/string_column.h:3,
                   from src/turbodbc_numpy/string_column.cpp:1:
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h: In function โ€˜void* PyArray_DATA(PyArrayObject*)โ€™:
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1462:43: error: โ€˜PyArrayObject_fieldsโ€™ has no member named โ€˜dataโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h: In function โ€˜char* PyArray_BYTES(PyArrayObject*)โ€™:
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1468:43: error: โ€˜PyArrayObject_fieldsโ€™ has no member named โ€˜dataโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h: At global scope:
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1471:19: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1477:19: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1483:19: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1489:19: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1495:44: error: โ€˜PyObjectโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1513:19: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1531:19: error: โ€˜PyObjectโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1539:52: error: โ€˜PyObjectโ€™ has not been declared
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h: In function โ€˜int PyArray_SETITEM(PyArrayObject*, char*, int*)โ€™:
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1541:53: error: โ€˜struct PyArray_ArrFuncsโ€™ has no member named โ€˜setitemโ€™
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h: At global scope:
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1580:19: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1739:5: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1772:5: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1777:5: error: โ€˜npy_intpโ€™ does not name a type
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1781:5: error: โ€˜PyObjectโ€™ does not name a type
  In file included from include/turbodbc_numpy/ndarrayobject.h:13:0,
                   from include/turbodbc_numpy/masked_column.h:3,
                   from include/turbodbc_numpy/string_column.h:3,
                   from src/turbodbc_numpy/string_column.cpp:1:
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h: In function โ€˜void PyArray_XDECREF_ERR(PyArrayObject*)โ€™:
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:166:16: error: โ€˜NULLโ€™ was not declared in this scope
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:168:68: error: โ€˜PyArray_BASEโ€™ was not declared in this scope
  /tmp/turbodbc/venv/local/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:172:22: error: โ€˜Py_DECREFโ€™ was not declared in this scope
  error: command 'gcc' failed with exit status 1

Apache Arrow result sets

In line with turbodbc_numpy it would be helpful to also have a turbodbc_arrow library that will produce Apache Arrow Tables / RecordBatches.

Numpy support

As a data scientist, I would like turbodbc to have a fast way to create numpy arrays, so I can efficiently work on large data sets (which still fit into memory).

Issue with decoding UTF8 strings from WCHAR buffers

If a field in a table contains (some, but not just any) Japanese characters, selecting these fields results in the following stacktrace:

SystemError: /builddir/build/BUILD/Python-3.5.3/Objects/listobject.c:307: bad argument to internal function

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/yalwan/.virtualenvs/fastpq/lib/python3.5/site-packages/turbodbc/exceptions.py", line 31, in wrapper
    return f(*args, **kwds)
  File "/home/yalwan/.virtualenvs/fastpq/lib/python3.5/site-packages/turbodbc/cursor.py", line 113, in fetchall
    return [row for row in self]
  File "/home/yalwan/.virtualenvs/fastpq/lib/python3.5/site-packages/turbodbc/cursor.py", line 113, in <listcomp>
    return [row for row in self]
  File "/home/yalwan/.virtualenvs/fastpq/lib/python3.5/site-packages/turbodbc/cursor.py", line 39, in __next__
    element = self.fetchone()
  File "/home/yalwan/.virtualenvs/fastpq/lib/python3.5/site-packages/turbodbc/exceptions.py", line 31, in wrapper
    return f(*args, **kwds)
  File "/home/yalwan/.virtualenvs/fastpq/lib/python3.5/site-packages/turbodbc/cursor.py", line 105, in fetchone
    result = self.result_set.fetch_row()
SystemError: <built-in method fetch_row of PyCapsule object at 0x7fc347b3d360> returned a result with an error set

Examples of Japanese strings known to cause the issue:

ใ‚ฝใƒ‹ใƒผใƒปใ‚ณใƒณใƒ”ใƒฅใƒผใ‚ฟใ‚จใƒณใ‚ฟใƒ†ใ‚คใƒณใƒกใƒณใƒˆ
ใ‚ฝใƒ‹ใƒผใƒปใƒ”ใ‚ฏใƒใƒฃใƒผใ‚บ ใ‚จใƒณใ‚ฟใƒ†ใ‚คใƒณใƒกใƒณใƒˆ
ใƒ™ใ‚ปใ‚นใƒ€ใƒปใ‚ฝใƒ•ใƒˆใƒฏใƒผใ‚ฏใ‚น๏ผใ‚ผใƒ‹ใƒžใƒƒใ‚ฏใ‚นใƒปใ‚ขใ‚ธใ‚ข(ๆ ช)

Request for fetchmanynumpy

Fetchall numpy is a good option when the data set fits in memory, but what about when we need to operate in batches? Can we get support for fetchmany numpy?

Cannot connect

I'm pretty sure I have a valid ODBC setup

If I do pyodbc.connect('DSN=dsn') it works fine

With turboodbc, I get this:

  File "/home/yalwan/venv/lib/python3.5/site-packages/turbodbc/exceptions.py", line 31, in wrapper
    return f(*args, **kwds)
  File "/home/yalwan/venv/lib/python3.5/site-packages/turbodbc/connect.py", line 40, in connect
    connection = Connection(intern_connect(_make_connection_string(dsn, **kwargs)))
turbodbc_intern.Error: ODBC error
state: IM002
native error code: 0
message: [unixODBC][Driver Manager]Data source name not found, and no default driver specified

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/yalwan/venv/lib/python3.5/site-packages/turbodbc/exceptions.py", line 33, in wrapper
    raise DatabaseError(str(e))
turbodbc.exceptions.DatabaseError: ODBC error
state: IM002
native error code: 0
message: [unixODBC][Driver Manager]Data source name not found, and no default driver specified

And not only this, but it happens regardless of what I pass to connect, empty string, DSN, or DSN-less with the parameters specified inline.

Package    Version 
---------- --------
appdirs    1.4.2   
packaging  16.8    
pip        9.0.1   
pybind11   2.0.1   
pyodbc     4.0.13  
pyparsing  2.1.10  
setuptools 34.3.1  
six        1.10.0  
turbodbc   1.0.3   
wheel      0.30.0a0

The database type I am trying to connect to is netezza (IBM puredata for analytics).

Please let me know if you require more information.

SQL_SUCCESS_WITH_INFO is treated the same as SQL_ERROR

Had a quick look over the c++ part of the implementation and noted that there is a lot of code like this in the library:

if (return_code == SQL_SUCCESS) {
        return output_handle;
} else {
        throw cpp_odbc::error(level2.get_diagnostic_record(input_handle));
}

The issue here is, that the driver or the driver manager decide to return SQL_SUCCESS_WITH_INFO the operation would fail. Since I discovered this issue purely by reading the code, I can not provide a specific combination of driver, driver manager and actions to produce an actual Bug. It still seemed worthy pointing out, though.

Request to replace boost Gregorian with Standard C++ component

Currently, due to the use of boost::gregorian::date, dates which come from the RDBMS with years outside the range
1400 to 10000
will fail to convert

Replacing boost::gregorian::date with standard C++ library components should allow dates outside of this range, and move part of the way to reducing turbodbc dependency on boost.

Odd cursor rowcount values being returned

I'm getting strange values for the cursor rowcount value when running certain queries.

Here's my setup:
Python 3.4.4, running on CentOS 6.6
MS SQL Server 2008 R2
Using the Microsoft ODBC Driver 11 for SQL Server on Linux with unixODBC 2.3.2

Here is an interactive session:

>>> crsr.execute("insert into dbo.turbodbc (col_int, col_str_a, col_str_u) values (1, 'a', 'b'), (2, 'c', 'd')")  # this succeeds
>>> crsr.rowcount  # expecting the answer 2
0                  # !!!!!!
>>> conn.commit()
>>> crsr.rowcount  # still expecting the answer 2
0                  # !!!!!!
>>>
>>> crsr.execute("insert into dbo.turbodbc (col_int, col_str_a, col_str_u) values (?, ?, ?)", (3, 'a', 'b'))  # this succeeds
>>> crsr.rowcount  # expecting the answer 1
1                  # yes!
>>> conn.commit()
>>> crsr.rowcount  # expecting the answer 1
1                  # yes!
>>>
>>> crsr.executemany("insert into dbo.turbodbc (col_int, col_str_a, col_str_u) values (?, ?, ?)", ((4, 'a', 'b'), (5, 'c', 'd')))  # this succeeds
>>> crsr.rowcount  # expecting the answer 2
2                  # yes!
>>> conn.commit()
>>> crsr.rowcount  # expecting the answer 2
2                  # yes!
>>>
>>> crsr.executemany("insert into dbo.does_not_exist (col_int, col_str_a, col_str_u) values (?, ?, ?)", ((4, 'a', 'b'), (5, 'c', 'd')))  # this fails
Traceback (most recent call last):
  File "/home/erskinek/venvs/turbodbc/lib/python3.4/site-packages/turbodbc/exceptions.py", line 31, in wrapper
    return f(*args, **kwds)
  File "/home/erskinek/venvs/turbodbc/lib/python3.4/site-packages/turbodbc/cursor.py", line 84, in executemany
    self.impl.prepare(sql)
turbodbc_intern.Error: ODBC error
state: 42S02
native error code: 208
message: [Microsoft][ODBC Driver 11 for SQL Server][SQL Server]Invalid object name 'dbo.does_not_exist'.

...

>>> crsr.rowcount  # expecting -1 because the previous executemany() call failed
2                  # !!!!!!
>>>
>>> crsr.execute("select * from dbo.turbodbc")  # this succeeds
>>> crsr.rowcount  # hoping for a positive integer (but the total number of rows might not yet be available)
-1                 # !!!!!!
>>> rows = crsr.fetchall()  # this succeeds
>>> crsr.rowcount  # definitely expecting a positive integer now
-1                 # !!!!!!
>>> conn.commit()
>>> crsr.rowcount  # still expecting a positive integer
-1                 # !!!!!!
>>>

I appear to be getting the expected rowcount value when using parameters, but not otherwise. Also, the rowcount value does not appear to be reset to some default value (i.e. -1) before the execute...() calls are made. This causes the old rowcount value to be retained, I believe incorrectly.

Latin Extended-A characters being converted to ASCII on INSERT

If I insert a Latin Extended-A character into my MS SQL Server database, it appears to be getting converted to its ASCII equivalent character.

Here's my setup:
Python 3.4.4, running on CentOS 6.6
MS SQL Server 2008 R2
Using the Microsoft ODBC Driver 11 for SQL Server on Linux with unixODBC 2.3.2

create table dbo.turbodbc (
  col_int int null,
  col_str_a varchar(100) null,  -- ascii (single-byte per character) column
  col_str_u nvarchar(100) null  -- unicode (actually UCS2 LE, two bytes per character) column
)
# the following string has three test characters separated by spaces:
#   a normal "ascii" character c, hex value \x63
#   c-cedilla, from "Latin-1 Supplement" but still a one byte value \xE7
#   c-with-an-acute-accent, from "Latin Extended-A", i.e. needs two bytes, value \x0107
# see http://inamidst.com/stuff/unidata/ for reference
string = 'c \xe7 \u0107'
row = [1, string, string]
sql = "insert into dbo.turbodbc (col_int, col_str_a, col_str_u) values (?, ?, ?)"
crsr = conn.cursor()
crsr.execute(sql, row)
conn.commit()

If I query for the hex equivalent of the two columns in the table, I get: 0x6320E72063 and 0x63002000E70020006300. As you can see, the third test character has been converted from c-with-an-acute-accent to plain old c, in both columns. I can kind-of understand this would happen in the first (ascii) column because the column can contain only single-byte characters, but the second "unicode" column should be able to handle this and hence contain 0x63002000E70020000701, i.e. end with 0701 not 6300 (note the little-endianness).

Somewhere along the line, the "Latin Extended-A" character \u0107 is being translated to \u0063, even if the target column is a unicode column. Would this be happening within turbodbc? Or somewhere else? Is turbodbc designed to work only with single-byte characters?

Allocating more than one Environment within a process is undefined behaviour

While wrapping ODBC for rust I noted race conditions while executing tests in parallel. Turns out it is undefined behaviour to have more than one environment allocated within a process.

#include "turbodbc/connect.h"
#include <cpp_odbc/make_environment.h>

turbodbc::connection turbodbc::connect(std::string const & connection_string)
{
	auto environment = cpp_odbc::make_environment();
	return {environment->make_connection(connection_string)};
}

The above code implies that turbodbc allocates an environment together with a connection, this makes having more than one connection at a time illegal within turbodbc. Due to pythons global interpreter lock I would have a hard time reproducing the same race condition I stumbled upon in unsafe rust, yet I wanted to race awareness of the issue in case there might be other issues.

See Koka/odbc-rs#12 for the original issue.

Not buildable from source tarball due to pybind11

When building from a source tarball I get

CMake Error at CMakeLists.txt:8 (add_subdirectory):
  The source directory

    /Users/ukorn/miniconda3/conda-bld/turbodbc_1487312827180/work/turbodbc-1.0.1/pybind11

  does not contain a CMakeLists.txt file.

It would be helpful to specify the pybind11 location separately instead of relying on the vendored one.

Postgresql TIME column unsupported type identifier

Using: postgresql 9.5 (postgresql95-odbc-09.05.0400-1PGDG.rhel7.x86_64) ODBC
Postgresql 9.5
Turbodbc 1.1.1
Python 2.7.5

Table definition:

 \d t1
               Table "public.t1"
 Column |           Type            | Modifiers
--------+---------------------------+-----------
 c1     | character varying(10)     |
 d1     | date                      |
 t1     | time(0) without time zone |

Program snippet:

        con=connectPGSQL()
        mscur = con.cursor()
        msinsert='insert into t1 ( c1,d1,t1 ) values( ? , ? , ? )'
        mscur.executemany(msinsert,rows)

Error:

RuntimeError: Error! Unsupported type identifier for column parameter_3 @ NULLABLE SQL_TYPE_TIME (precision 8, scale -1))

growth strategy for unknown parameter types does not work with EXASOL

If you execute a parametrised query where EXASOL does not know exactly the type, like:
cursor.execute("SELECT x from (values(1), (2)) as tbl (x) where x = ?;" , [2,])
turbodbc allocates a huge amount of memory. This combined with the default value for parameter_sets_to_buffer could lead to a MemoryError.

SQL Server: crash on conn.close() without rollback/commit

When closing a connection (only after cursor usage), I get the following error:

terminate called after throwing an instance of 'cpp_odbc::error'
  what():  ODBC error
state: 25000
native error code: 0
message: [Microsoft][ODBC Driver 13 for SQL Server]Invalid transaction state

Script to reproduce the error:

import turbodbc

conn = turbodbc.connect(driver='ODBC Driver 13 for SQL Server', 
    server='xxx', port='1433', uid='xxx', pwd='xxx')
cursor = conn.cursor()
cursor.execute("SELECT * FROM sys.tables")
cursor.close()
conn.close()

This can be prevented by calling conn.rollback() or conn.commit() before closing the connection, since turbodbc connects to SQL Server in manual commit mode, which means all commands will be running inside of a transaction as soon as you open a cursor, and closing a connection before closing the transaction will cause this error.

Specifications:
Fedora 25 - 64 bit
Python 3.5.2
Turbodbc 1.0.0
unixODBC 2.3.4
ODBC Driver: msodbcsql-13.1.4.0-1 (official Microsoft driver)

Python 2.7 Windows Support

Hello,

I stumbled across this while looking for an alternative to pyodbc for an ETL application that I've built using pandas and sqlalchemy. Because of existing design decisions and my organization's internal IT structure, I'm somewhat stuck using Windows Server and MS SQL Server for hosting the app and data that I'm processing. The current application is built in Python 2.7 and everything works great except for very slow insert times with pyodbc for large (10,000 - 400,000) datasets into MSSQL. I have adapted a "fast_load" workstream with ceODBC, but it doesn't seem to be actively developed and some of my data sets have NVARCHAR('max') fields that throw an error when the values are too large (doesn't happen with pyodbc).

Long story short, I'd like to replace them both with one module that is fast and can handle the large strings. Am I in the right place?

I saw that Windows support was recently released for Python 3.5+. Is there any chance of getting Python 2.7 support also? I'd be willing to help implement the necessary changes to downgrade, but I thought I'd see what the general thoughts on the level of difficulty is first.

tuple should be valid parameter type for parameters

Using tuples as parameters for an INSERT statement results in the following Exception.

ArgumentError Traceback (most recent call last)
in ()
----> 1 c.execute("INSERT INTO {0} VALUES (?, ?, ?, ?) RETURNING {0}.id".format('users'), (7, 'Max', 'Mustermann', None))

/home/vagrant/.virtualenvs/turbodbc_sqlalchemy/local/lib/python2.7/site-packages/turbodbc/exceptions.pyc in wrapper(_args, *_kwds)
23 def wrapper(_args, *_kwds):
24 try:
---> 25 return f(_args, *_kwds)
26 except InternError as e:
27 raise DatabaseError(str(e))

/home/vagrant/.virtualenvs/turbodbc_sqlalchemy/local/lib/python2.7/site-packages/turbodbc/cursor.py in execute(self, sql, parameters)
40 self.impl.prepare(sql)
41 if parameters:
---> 42 self.impl.add_parameter_set(parameters)
43 self.impl.execute()
44 self.rowcount = self.impl.get_row_count()

ArgumentError: Python argument types in
Cursor.add_parameter_set(Cursor, tuple)
did not match C++ signature:
add_parameter_set(turbodbc::cursor {lvalue}, std::vector<boost::optional<boost::variant<long, std::string, bool, double, boost::gregorian::date, boost::posix_time::ptime, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_> >, std::allocator<boost::optional<boost::variant<long, std::string, bool, double, boost::gregorian::date, boost::posix_time::ptime, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_> > > >)

Option to override numpy dtype for decimals

I'm pulling some numbers that are represented as 'length 38 numeric' type in SQL Server (even though the size is overkill for the actual data), and turbodbc is converting them to strings (as stated here). Would it be possible to allow the user to specify that these be returned as floats?

NumPy support for parameters

As a data scientist, I would like to use column-based NumPy arrays as parameters of queries, so I can efficiently perform bulk inserts of my data.

Return rows as native Python lists

Currently, turbodbc returns rows as a dedicated type created by boost::python. This type is not directly printable and adds confusion. Replace this type with a standard Python list.

In addition, before turbodbc converts result set values to Python objects, there is an intermediate step in converting result set values to a C++ std::vector<turbodbc::optional_field>, which is in turn converted to a Python object. This is pretty costly and unnecessary. Both issues can be fixed in a single effort.

Unhandled exception crashes Python process

When connections are lost, the Python process terminates with the following error message:

terminate called after throwing an instance of 'cpp_odbc::error'
  what():  ODBC error
state: 40004
native error code: -1
message: [EXASOL][EXASolution driver]Connection lost.
Aborted

It seems that the cpp_odbc::error is not translated to a turbodbc::error that would be known to the Python interpreter.

Support binary types

Feature request, SQL_VARBINARY / SQL_LONGVARBINARY does not seem to work today.

Tried this with postgresql and python 3.5

CREATE TABLE mybtest
(
  fooid integer,
  foobin bytea
);
insert into mybtest (fooid, foobin) values (123, 'foo');
from turbodbc import connect
conn = connect(DRIVER="PostgreSQL ANSI", ...)
cursor = conn.cursor()
cursor.execute("select * from mybtest")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "python3.5/site-packages/turbodbc/exceptions.py", line 31, in wrapper
    return f(*args, **kwds)
  File "python3.5/site-packages/turbodbc/cursor.py", line 72, in execute
    self.impl.execute()
RuntimeError: Error! Unsupported type identifier '-3'

Determine number of buffered rows according to memory budget

As a turbodbc user, I would like to specify how much memory turbodbc should use for buffering result sets, so I can deal with tables with large fields.

Context

Some tables such as Exasol's sys.exa_all_views contain very large string columns for storing SQL queries, for example. In the aforementioned case, the length of the sole returned column was specified by the driver as 8,000,000.

With turbodbc's fixed number of rows buffered being set to 1,000 by default, the buffer for such a column amounts to roughly 8 GB.

If one could specify that the buffer target size is 200 MB, for example, turbodbc could automatically determine the number of buffered rows based on the size of individual columns.

Add Python 3 compatibility

Developing new libraries with no Python 3 compatibility doesn't help our cause.
Python 3 is the future and the future starts now ;-)

Feature-Request: Release GIL

As a (generic) user, I want turbodbc to release the GIL to allow concurrent usage.

Currently, turbodbc does not release the GIL. Thereby, it is not possible to use python threading effectively with turbodbc. By releasing the GIL, turbodbc would allow running multiple queries concurrently or execute queries in the background of an jupyter notebook without locking it completely. For example, psycopg does release the GIL.

Make execute() return the cursor

It would be handy if the cursor's execute() function returned the cursor itself (rather than None) so that it would be possible to write code like this:

rows = cursor.execute('select * from my_table').fetchall()

rather than having to take two bites at it:

cursor.execute('select * from my_table')
rows = cursor.fetchall()

Ditto for executemany().

FreeTDS: cannot execute with params

Using FreeTDS I cannot execute an INSERT statement with parameters. I get the following error:

DatabaseError: ODBC error
state: IM001
native error code: 0
message: [unixODBC][Driver Manager]Driver does not support this function

From the unixODBC trace:

[ODBC][58773][1487672064.768219][SQLDescribeParam.c][185]
		Entry:
			Statement = 0x7fee40014400
			Parameter Number = 1
			SQL Type = 0x7fff5e9343be
			Param Def = 0x7fff5e9343b0
			Scale = 0x7fff5e9343ae
			Nullable = 0x7fff5e9343ac
[ODBC][58773][1487672064.768731][SQLDescribeParam.c][292]Error: IM001

To reproduce:

conn = turbodbc.connect(dsn='mssql', uid='test', pwd='test')
cursor = conn.cursor()
cursor.execute("CREATE TABLE test_insert (val INT);")
cursor.execute("INSERT INTO test_insert (val) VALUES (?);", (0,))

Doing an insert without parameterization works fine, e.g.
cursor.execute("INSERT INTO test_insert (val) VALUES (42);")
works fine.

Full specs: using FreeTDS 1.00.26, unixODBC 2.3.4, Python 3.5.2, macOS Sierra, SQL Server 2016.

Q: Is there a way to use this with ORMs, such as SQLAlchemy?

This looks awesome.

Is it as simple as swapping out a connection string for our existing pyodbc string?
connection_string = 'mssql+pyodbc:///?odbc_connect=%s' % connect_str
We're currently using a FreeTDS driver, would we change that?

Thanks

Add integration tests

Rework the integration tests so that it is possible to run the integration tests on travis and with a customizable set of databases.

Support for SQL_GUID type

Querying a MS SQL Server table that has a SQL_GUID type column will make turbodbc raise a RuntimeError:

  File "/Users/Dirkjonker/venv/lib/python3.5/site-packages/turbodbc/exceptions.py", line 31, in wrapper
    return f(*args, **kwds)
  File "/Users/Dirkjonker/venv/lib/python3.5/site-packages/turbodbc/cursor.py", line 72, in execute
    self.impl.execute()
RuntimeError: Error! Unsupported type identifier '-11'

$ grep "(-11)" /usr/local/include/sql*.h
/usr/local/include/sqlext.h:#define SQL_GUID                            (-11)

For our use case, returning the GUID as a string or bytestring would be sufficient.

macOS Support

Turbodbc currently does not build on macOS. The current error message is

Undefined symbols for architecture x86_64:
  "_PyBool_FromLong", referenced from:
      boost::python::converter::arg_to_python<bool>::arg_to_python(bool const&) in python_result_set.cpp.o
  "_PyCapsule_Import", referenced from:
      turbodbc::result_sets::python_result_set::python_result_set(turbodbc::result_sets::result_set&) in python_result_set.cpp.o
  "_PyFloat_FromDouble", referenced from:
      boost::python::converter::arg_to_python<double>::arg_to_python(double const&) in python_result_set.cpp.o
  "_PyInt_FromLong", referenced from:
      boost::python::converter::arg_to_python<long>::arg_to_python(long const&) in python_result_set.cpp.o
  "_PyUnicodeUCS2_FromString", referenced from:
      turbodbc::result_sets::(anonymous namespace)::make_object(turbodbc::type_code, char const*) in python_result_set.cpp.o
  "__Py_NoneStruct", referenced from:
      boost::python::api::object::object() in connect.cpp.o
      boost::python::api::object::object() in connection.cpp.o
      boost::python::api::object::object() in cursor.cpp.o
      boost::python::api::object::object() in python_result_set.cpp.o
      turbodbc::result_sets::(anonymous namespace)::make_timestamp(tagTIMESTAMP_STRUCT const&) in python_result_set.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.

This could be fixed by adjusting linker settings in CMake for macOS but there are probably more issues in the build on macOS. Furthermore we should activate Travis builds for macOS once we have a running variant.

Cannot build a wheel package with `pip wheel`

In principle, for most Python sdists on the pypi, I can build a wheel distributable with something along the lines of pip wheel turbodbc --no-binary :all:.

For turbodbc I then get the error:

  running build_ext
  building 'libturbodbc' extension
  Traceback (most recent call last):
    File "<string>", line 1, in <module>
    File "/tmp/pip-build-AW6WjO/turbodbc/setup.py", line 159, in <module>
      install_requires=['pybind11>=2.0.0', 'six']
    File "/usr/lib/python2.7/distutils/core.py", line 151, in setup
      dist.run_commands()
    File "/usr/lib/python2.7/distutils/dist.py", line 953, in run_commands
      self.run_command(cmd)
    File "/usr/lib/python2.7/distutils/dist.py", line 972, in run_command
      cmd_obj.run()
    File "/tmp/venv/local/lib/python2.7/site-packages/wheel/bdist_wheel.py", line 179, in run
      self.run_command('build')
    File "/usr/lib/python2.7/distutils/cmd.py", line 326, in run_command
      self.distribution.run_command(command)
    File "/usr/lib/python2.7/distutils/dist.py", line 972, in run_command
      cmd_obj.run()
    File "/usr/lib/python2.7/distutils/command/build.py", line 128, in run
      self.run_command(cmd_name)
    File "/usr/lib/python2.7/distutils/cmd.py", line 326, in run_command
      self.distribution.run_command(command)
    File "/usr/lib/python2.7/distutils/dist.py", line 972, in run_command
      cmd_obj.run()
    File "/tmp/venv/local/lib/python2.7/site-packages/setuptools/command/build_ext.py", line 68, in run
      _build_ext.run(self)
    File "/tmp/venv/local/lib/python2.7/site-packages/Cython/Distutils/old_build_ext.py", line 185, in run
      _build_ext.build_ext.run(self)
    File "/usr/lib/python2.7/distutils/command/build_ext.py", line 337, in run
      self.build_extensions()
    File "/tmp/venv/local/lib/python2.7/site-packages/Cython/Distutils/old_build_ext.py", line 193, in build_extensions
      self.build_extension(ext)
    File "/tmp/venv/local/lib/python2.7/site-packages/setuptools/command/build_ext.py", line 180, in build_extension
      _build_ext.build_extension(self, ext)
    File "/usr/lib/python2.7/distutils/command/build_ext.py", line 496, in build_extension
      depends=ext.depends)
    File "/usr/lib/python2.7/distutils/ccompiler.py", line 566, in compile
      depends, extra_postargs)
    File "/usr/lib/python2.7/distutils/ccompiler.py", line 355, in _setup_compile
      pp_opts = gen_preprocess_options(macros, incdirs)
    File "/usr/lib/python2.7/distutils/ccompiler.py", line 1051, in gen_preprocess_options
      pp_opts.append ("-I%s" % dir)
    File "/tmp/pip-build-AW6WjO/turbodbc/setup.py", line 61, in __str__
      import pybind11
  ImportError: No module named pybind11

  ----------------------------------------
  Failed building wheel for turbodbc

If I install pybind11 into the virtualenv, the build does not fail that early. However, I can see that pip downloads a source distribution for pybind11 again (even though it is already installed).

Can't build master on macOS Sierra

I can't build the latest master on macOS Sierra anymore using Python 3.5 or 3.6.

During make:

[ 10%] Building CXX object cpp/cpp_odbc/Library/CMakeFiles/cpp_odbc.dir/src/level2/level1_connector.cpp.o
/Users/Dirkjonker/src/turbodbc/cpp/cpp_odbc/Library/src/level2/level1_connector.cpp:361:43: error: no matching member function for call to 'prepare_statement'
    auto const return_code = level1_api_->prepare_statement(handle.handle, buffered.data_pointer(), buffered.size());
                             ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~
/Users/Dirkjonker/src/turbodbc/cpp/cpp_odbc/Library/cpp_odbc/level1/api.h:117:15: note: candidate function not viable: no known conversion from 'unsigned short *' to 'SQLCHAR *'
      (aka 'unsigned char *') for 2nd argument
    SQLRETURN prepare_statement(SQLHSTMT statement_handle, SQLCHAR * statement_text, SQLINTEGER text_length) const;
              ^
/Users/Dirkjonker/src/turbodbc/cpp/cpp_odbc/Library/cpp_odbc/level1/api.h:122:15: note: candidate function not viable: no known conversion from 'unsigned short *' to 'SQLWCHAR *'
      (aka 'wchar_t *') for 2nd argument
    SQLRETURN prepare_statement(SQLHSTMT statement_handle, SQLWCHAR * statement_text, SQLINTEGER text_length) const;
              ^
1 error generated.
make[2]: *** [cpp/cpp_odbc/Library/CMakeFiles/cpp_odbc.dir/src/level2/level1_connector.cpp.o] Error 1
make[1]: *** [cpp/cpp_odbc/Library/CMakeFiles/cpp_odbc.dir/all] Error 2
make: *** [all] Error 2

1.0.5 builds without any errors. Also, on Centos 7, no problems.

C++ Code Style

Before we have more discussion on my Arrow PR that our C++ coding styles differ, I would prefer to have a clang-format configuration so that we could just run make format to align the coding styles automatically.

Using dot notation on returned rows

It would be handy if the cursor's fetch() functions returned something like named tuples so that the fields can be accessed using dot notation rather than having to refer to them by index.

cursor.execute("select first_name, last_name from person")
row = cursor.fetchone()
print('Hello {}'.format(row[0]))          # this currently works
print('Hello {}'.format(row.first_name))  # this is not yet possible

Datetime field overflow for MSSQL

When using a DATETIME2 parameter with non-zero fractional seconds for MSSQL databases, the following error message occurs:

[Microsoft][ODBC Driver 13 for SQL Server]Datetime field overflow. Fractional second precision exceeds the scale specified in the parameter binding.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.