techouse / sqlite3-to-mysql

Transfer data from SQLite to MySQL

Home Page:https://techouse.github.io/sqlite3-to-mysql/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Accept `INTEGER PRIMARY KEY DEFAULT 0` construct

rasa opened this issue · comments

Describe the bug

Converting

id INTEGER PRIMARY KEY DEFAULT 1

fails with

MySQL failed creating table const: 1067 (42000): Invalid default value for 'id'

Expected behaviour

To succeed.

Actual result

See above.

System Information

| software               | version                              |
|------------------------|--------------------------------------|
| sqlite3-to-mysql       | 1.4.16                               |
|                        |                                      |
| Operating System       | Windows 10                           |
| Python                 | CPython 3.10.9                       |
| MySQL                  | MySQL client not found on the system |
| SQLite                 | 3.39.4                               |
|                        |                                      |
| click                  | 8.1.3                                |
| mysql-connector-python | 8.0.29                               |
| pytimeparse            | 1.1.8                                |
| simplejson             | 3.18.4                               |
| six                    | 1.16.0                               |
| tabulate               | 0.9.0                                |
| tqdm                   | 4.64.1                               |

Additional context

2023-03-27 21:55:58 ERROR    MySQL failed creating table const: 1067 (42000): Invalid default value for 'id'
Traceback (most recent call last):
  File "C:\Python310\lib\runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Python310\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "C:\Python310\Scripts\sqlite3mysql.exe\__main__.py", line 7, in <module>
  File "C:\Python310\lib\site-packages\click\core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
  File "C:\Python310\lib\site-packages\click\core.py", line 1055, in main
    rv = self.invoke(ctx)
  File "C:\Python310\lib\site-packages\click\core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "C:\Python310\lib\site-packages\click\core.py", line 760, in invoke
    return __callback(*args, **kwargs)
  File "C:\Python310\lib\site-packages\sqlite3_to_mysql\cli.py", line 204, in cli
    converter.transfer()
  File "C:\Python310\lib\site-packages\sqlite3_to_mysql\transporter.py", line 706, in transfer
    self._create_table(table["name"], transfer_rowid=transfer_rowid)
  File "C:\Python310\lib\site-packages\sqlite3_to_mysql\transporter.py", line 386, in _create_table
    self._mysql_cur.execute(sql)
  File "C:\Python310\lib\site-packages\mysql\connector\cursor.py", line 1209, in execute
    self._prepared = self._connection.cmd_stmt_prepare(operation)
  File "C:\Python310\lib\site-packages\mysql\connector\connection.py", line 1423, in cmd_stmt_prepare
    result = self._handle_binary_ok(packet)
  File "C:\Python310\lib\site-packages\mysql\connector\connection.py", line 1363, in _handle_binary_ok
    raise errors.get_exception(packet)
mysql.connector.errors.ProgrammingError: 1067 (42000): Invalid default value for 'id'

That's not possible due to database limitations. Primary keys can't default to 0. Set them to auto increment in this case. https://stackoverflow.com/questions/5427142/sql-primary-key-can-accept-0

Sqlite allowed it. I tried 1 and it failed on that too. The workaround was to remove the default, and insert NULL, which generates the next id, in this case 1.

id INTEGER PRIMARY KEY NOT NULL

The target database, MySQL, does not allow this.

The target database, MySQL, does not allow this.

Of course. Hence my request. I guess you’re saying users should change the existing schema, and not expect this tool to do the needed conversion for them. Is that because we’re using SQLAlchemy under the hood, and so we can’t modify the DDL on the fly?

It doesn't use SQLAlchemy. It relies on plain SQL code generation. Check here how primary keys are transferred.

SQLite is much more forgiving than MySQL and this tool will not work with a custom/non-compliant DDL. This was never the intention.

It's up to the user to ensure that the DDL and data are standardized prior to conversion and correctly transferred and converted after.