pudo / dataset

Easy-to-use data handling for SQL data stores with support for implicit table creation, bulk loading, and transactions.
https://dataset.readthedocs.org/
MIT License
4.76k stars 297 forks source link

Mysql and Python 3.8 #390

Open ddofborg opened 2 years ago

ddofborg commented 2 years ago

I am trying to use dataset with MySQL 8.

I noticed MySQLDB is not really supported on Python3 and I found mysqlclient, which replaces MySQLDB for Python 3.

When I run the following:

import dataset
db = dataset.connect('mysql://un:pw@localhost')
db.tables()

I get:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/dataset/venv/lib/python3.8/site-packages/dataset/database.py", line 184, in tables
    return self.inspect.get_table_names(schema=self.schema)
  File "/home/dataset/venv/lib/python3.8/site-packages/sqlalchemy/engine/reflection.py", line 266, in get_table_names
    return self.dialect.get_table_names(
  File "<string>", line 2, in get_table_names
  File "/home/dataset/venv/lib/python3.8/site-packages/sqlalchemy/engine/reflection.py", line 55, in cache
    ret = fn(self, con, *args, **kw)
  File "/home/dataset/venv/lib/python3.8/site-packages/sqlalchemy/dialects/mysql/base.py", line 2786, in get_table_names
    % self.identifier_preparer.quote_identifier(current_schema)
  File "/home/dataset/venv/lib/python3.8/site-packages/sqlalchemy/sql/compiler.py", line 5120, in quote_identifier
    + self._escape_identifier(value)
  File "/home/dataset/venv/lib/python3.8/site-packages/sqlalchemy/sql/compiler.py", line 5079, in _escape_identifier
    value = value.replace(self.escape_quote, self.escape_to_quote)
AttributeError: 'NoneType' object has no attribute 'replace'

I get this error for basically all commands. Any ideas what this could be?

pudo commented 2 years ago

Hmmm I'm not sure what's happening there. Can you share the list of table names in the given database? One of them might contain only special characters and get normalized to None...

pudo commented 2 years ago

Wrong button, good morning :)

ddofborg commented 2 years ago

It's a clean install of MySQL v8 on Ubuntu, only default databases and tables. I do see a utf8mb4 encoding of the tables. Could that be it?

Screenshot 2021-12-23 at 10 51 05

PS. Maybe it's good to update the docs and remove MySQLDB from there.

ddofborg commented 2 years ago

If it helps, I can add the print somewhere to see the value before normalisation. Just let me know where normalisation happens, and I will print before that.

pudo commented 2 years ago

The only thing we're passing in there is schema, which is None as a default. This should be possible:

https://docs.sqlalchemy.org/en/14/core/reflection.html#sqlalchemy.engine.reflection.Inspector.get_table_names

Can you try and remove the self.schema from /home/dataset/venv/lib/python3.8/site-packages/dataset/database.py:184?

ddofborg commented 2 years ago

You mean from:

    @property
    def tables(self):
        """Get a listing of all tables that exist in the database."""
        return self.inspect.get_table_names(schema=self.schema)

to:

    @property
    def tables(self):
        """Get a listing of all tables that exist in the database."""
        return self.inspect.get_table_names()

Same thing...

pudo commented 2 years ago

Hmmm I really don't understand how this is caused by dataset. Have you checked the upstream bug tracker at sqlalchemy to see if the issue is documented there? I don't have MySQL set up to test so it's a bit hard to debug/replicate.