django.db.utils.OperationalError: (1050, "Table 'bar' already exists")
ulyssejdv opened this issue · comments
Hi :)
First of all, thank you very much for the package I think it will be very helpfull for the Django community.
Unfortunately i encounter some issues :( I'm sure I'm not using it the right way ...
There is an example of test I wrote.
@pytest.mark.django_db()
def test_should_copy_cads_validations_to_validations_demonstrations(migrator):
old_state = migrator.apply_initial_migration(
("validations", "0004_auto_20230623_1110")
)
# .. create some models here ..
new_state = migrator.apply_tested_migration(
("validations", "0005_auto_20230713_1115")
)
# After the initial migration is done, we can use the model state:
Bar = new_state.apps.get_model("foo", "Bar")
# .. some assert here ..
When I execute this test I have the folloing error :
django.db.utils.OperationalError: (1050, "Table 'foo_bar' already exists")
When i stop on a breakpoint in debug mode in my IDE, there are table already created before apply_initial_migration was called (the error source I think) but I don't understand why tables are already present. I execute this test in total isolation, make this there is no table in the DB.
If you have an idea, I will really appreciate :)
I use a MySQL 5.7, python 3.9, Django 3.2
hi @ulyssejdv,
can you say what line exactly inside apply_initial_migration
is causing the error?
Generally, in apply_initial_migration
we are dropping all models tables, before running migrations, so please double check foo.Bar
is really a Django model (not a DB view).
Do you use the --migrations
flag when running pytest
?
It will be really useful if you could create a PR or paste the simplest code that is causing the issue you have spotted, so we can debug it, help you, and potentially fix the problem in the project ;)
There is the full trace
Applying repairs.0022_auto_20230213_0904... OK
Applying repairs.0023_repairpartnumberevolution_order... OK
Applying sessions.0001_initial... OK
Applying validations.0001_initial... OK
Applying validations.0002_alter_demonstration_key_arguments... OK
Applying validations.0003_alter_validatedccl_demonstration... OK
Applying validations.0004_validatedmodificationexplication... OK
Applying validations.0005_auto_20230713_1115... OK
Creating test database for alias 'default' ('test_ecad')...
FAILED [100%]
tests\apps\validations\migrations\test_migration_0005.py:5 (test_should_copy_cads_validations_to_validations_demonstrations)
self = <django.db.backends.utils.CursorWrapper object at 0x000001D72EBB34F0>
sql = 'CREATE TABLE `cads_page` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `full_path` varchar(255) NOT NULL, `updated_at` datetime(6) NOT NULL, `doc_id` char(32) NOT NULL, `updated_by_id` integer NULL)'
params = None
ignored_wrapper_args = (False, {'connection': <django.db.backends.mysql.base.DatabaseWrapper object at 0x000001D72BE6B880>, 'cursor': <django.db.backends.utils.CursorWrapper object at 0x000001D72EBB34F0>})
def _execute(self, sql, params, *ignored_wrapper_args):
self.db.validate_no_broken_transaction()
with self.db.wrap_database_errors:
if params is None:
# params default might be backend specific.
> return self.cursor.execute(sql)
C:\SafApp\virtualenvs\ecad\lib\site-packages\django\db\backends\utils.py:82:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <django.db.backends.mysql.base.CursorWrapper object at 0x000001D72EC26EE0>
query = 'CREATE TABLE `cads_page` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `full_path` varchar(255) NOT NULL, `updated_at` datetime(6) NOT NULL, `doc_id` char(32) NOT NULL, `updated_by_id` integer NULL)'
args = None
def execute(self, query, args=None):
try:
# args is None means no string interpolation
> return self.cursor.execute(query, args)
C:\SafApp\virtualenvs\ecad\lib\site-packages\django\db\backends\mysql\base.py:73:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <MySQLdb.cursors.Cursor object at 0x000001D72EC26FD0>
query = b'CREATE TABLE `cads_page` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `full_path` varchar(255) NOT NULL, `updated_at` datetime(6) NOT NULL, `doc_id` char(32) NOT NULL, `updated_by_id` integer NULL)'
args = None
def execute(self, query, args=None):
"""Execute a query.
query -- string, query to execute on server
args -- optional sequence or mapping, parameters to use with query.
Note: If args is a sequence, then %s must be used as the
parameter placeholder in the query. If a mapping is used,
%(key)s must be used as the placeholder.
Returns integer represents rows affected, if any
"""
while self.nextset():
pass
db = self._get_db()
if isinstance(query, str):
query = query.encode(db.encoding)
if args is not None:
if isinstance(args, dict):
nargs = {}
for key, item in args.items():
if isinstance(key, str):
key = key.encode(db.encoding)
nargs[key] = db.literal(item)
args = nargs
else:
args = tuple(map(db.literal, args))
try:
query = query % args
except TypeError as m:
raise ProgrammingError(str(m))
assert isinstance(query, (bytes, bytearray))
> res = self._query(query)
C:\SafApp\virtualenvs\ecad\lib\site-packages\MySQLdb\cursors.py:206:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <MySQLdb.cursors.Cursor object at 0x000001D72EC26FD0>
q = b'CREATE TABLE `cads_page` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `full_path` varchar(255) NOT NULL, `updated_at` datetime(6) NOT NULL, `doc_id` char(32) NOT NULL, `updated_by_id` integer NULL)'
def _query(self, q):
db = self._get_db()
self._result = None
> db.query(q)
C:\SafApp\virtualenvs\ecad\lib\site-packages\MySQLdb\cursors.py:319:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <_mysql.connection open to '127.0.0.1' at 000001D72B6DD8F0>
query = b'CREATE TABLE `cads_page` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `full_path` varchar(255) NOT NULL, `updated_at` datetime(6) NOT NULL, `doc_id` char(32) NOT NULL, `updated_by_id` integer NULL)'
def query(self, query):
# Since _mysql releases GIL while querying, we need immutable buffer.
if isinstance(query, bytearray):
query = bytes(query)
> _mysql.connection.query(self, query)
E MySQLdb._exceptions.OperationalError: (1050, "Table 'cads_page' already exists")
C:\SafApp\virtualenvs\ecad\lib\site-packages\MySQLdb\connections.py:259: OperationalError
The above exception was the direct cause of the following exception:
@pytest.mark.django_db(transaction=True)
def test_should_copy_cads_validations_to_validations_demonstrations():
"""Ensures that the initial migration works."""
migrator = Migrator(database="default")
> old_state = migrator.apply_initial_migration(
("validations", "0004_validatedmodificationexplication"),
)
test_migration_0005.py:12:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
C:\SafApp\virtualenvs\ecad\lib\site-packages\django_test_migrations\migrator.py:61: in apply_initial_migration
return self._migrate(targets, plan=plan)
C:\SafApp\virtualenvs\ecad\lib\site-packages\django_test_migrations\migrator.py:84: in _migrate
return self._executor.migrate(migration_targets, plan=plan)
C:\SafApp\virtualenvs\ecad\lib\site-packages\django\db\migrations\executor.py:117: in migrate
state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
C:\SafApp\virtualenvs\ecad\lib\site-packages\django\db\migrations\executor.py:147: in _migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
C:\SafApp\virtualenvs\ecad\lib\site-packages\django\db\migrations\executor.py:227: in apply_migration
state = migration.apply(state, schema_editor)
C:\SafApp\virtualenvs\ecad\lib\site-packages\django\db\migrations\migration.py:126: in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
C:\SafApp\virtualenvs\ecad\lib\site-packages\django\db\migrations\operations\models.py:92: in database_forwards
schema_editor.create_model(model)
C:\SafApp\virtualenvs\ecad\lib\site-packages\django\db\backends\base\schema.py:345: in create_model
self.execute(sql, params or None)
C:\SafApp\virtualenvs\ecad\lib\site-packages\django\db\backends\base\schema.py:145: in execute
cursor.execute(sql, params)
C:\SafApp\virtualenvs\ecad\lib\site-packages\django\db\backends\utils.py:66: in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
C:\SafApp\virtualenvs\ecad\lib\site-packages\django\db\backends\utils.py:75: in _execute_with_wrappers
return executor(sql, params, many, context)
C:\SafApp\virtualenvs\ecad\lib\site-packages\django\db\backends\utils.py:84: in _execute
return self.cursor.execute(sql, params)
C:\SafApp\virtualenvs\ecad\lib\site-packages\django\db\utils.py:90: in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
C:\SafApp\virtualenvs\ecad\lib\site-packages\django\db\backends\utils.py:82: in _execute
return self.cursor.execute(sql)
C:\SafApp\virtualenvs\ecad\lib\site-packages\django\db\backends\mysql\base.py:73: in execute
return self.cursor.execute(query, args)
C:\SafApp\virtualenvs\ecad\lib\site-packages\MySQLdb\cursors.py:206: in execute
res = self._query(query)
C:\SafApp\virtualenvs\ecad\lib\site-packages\MySQLdb\cursors.py:319: in _query
db.query(q)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <_mysql.connection open to '127.0.0.1' at 000001D72B6DD8F0>
query = b'CREATE TABLE `cads_page` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `full_path` varchar(255) NOT NULL, `updated_at` datetime(6) NOT NULL, `doc_id` char(32) NOT NULL, `updated_by_id` integer NULL)'
def query(self, query):
# Since _mysql releases GIL while querying, we need immutable buffer.
if isinstance(query, bytearray):
query = bytes(query)
> _mysql.connection.query(self, query)
E django.db.utils.OperationalError: (1050, "Table 'cads_page' already exists")
C:\SafApp\virtualenvs\ecad\lib\site-packages\MySQLdb\connections.py:259: OperationalError
I tried to switch to sqlite to test if the error only concerned MySQL but I have the same issue ^^
In django_test_migrations.sql when we try to get all table, there is only one missing ... the cads_page table ^^
tables = connection.introspection.django_table_names(
only_existing=True,
include_views=False,
)
I will search why !
Final update (I think) :
I don't know why but django core api ignored one of my model...
I have the followed project structure :
apps/
- cads/
- models/
- shared.py ( with some models)
- pages.py ( with class Page(models.Model): )
I move Page from pages.py to shared.py and it works....
Thank you very much for your support :) this a realy helpfull django package <3
I close the issue but if want more details or keep me as tester PM me !
@ulyssejdv thank you!
It seems like your Page
model from apps/cads/models/pages.py
was not imported in a proper place (at Django, you need to put models into the models
package - either models.py
or models/__init__.py
) or import them in the app ready
hook method.
Reference: https://docs.djangoproject.com/en/5.0/topics/db/models/#organizing-models-in-a-package