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.