Guo*_*aqi 5 python django django-models
例如,我有一个包含两个应用程序(myapp、myapp2)的项目(mysite)。这些应用程序使用不同的数据库:
\n\n设置.py:
\n\nDATABASES = {\n "default": {\n "ENGINE": "django.db.backends.postgresql",\n "HOST": "127.0.0.1",\n "USER": "postgres",\n "PASSWORD": "root",\n "PORT": "5432",\n "NAME": "test",\n },\n "test": {\n "ENGINE": "django.db.backends.mysql",\n "HOST": "127.0.0.1",\n "USER": "root",\n "PASSWORD": "root",\n "PORT": "3306",\n "NAME": "test",\n },\n}\nRun Code Online (Sandbox Code Playgroud)\n\n然后我编写一个数据库路由器:
\n\nfrom django.conf import settings\n\n\nclass AppRouter:\n def db_for_read(self, model, **hints):\n return settings.APP_DB_MAPPER.get(model._meta.app_label)\n\n def db_for_write(self, model, **hints):\n return settings.APP_DB_MAPPER.get(model._meta.app_label)\n\n def allow_relation(self, obj1, obj2, **hints):\n db1 = settings.APP_DB_MAPPER.get(obj1._meta.app_label)\n db2 = settings.APP_DB_MAPPER.get(obj2._meta.app_label)\n if db1 and db2:\n if db1 == db2:\n return True\n else:\n return False\n return None\n\n def allow_migrate(self, db, app_label, model_name=None, **hints):\n if app_label in settings.APP_DB_MAPPER:\n return db == settings.APP_DB_MAPPER[app_label]\n return None\n\nRun Code Online (Sandbox Code Playgroud)\n\n然后应用它。
\n\n设置.py:
\n\nDATABASE_ROUTERS = ["mysite.app_router.AppRouter"]\n\nAPP_DB_MAPPER = {"myapp": "default", "myapp2": "test"}\nRun Code Online (Sandbox Code Playgroud)\n\n在每个应用程序中添加一个模型:
\n\nmyapp/models.py:
\n\nfrom django.db import models\nfrom django.contrib.auth.models import User\n\n\nclass TestDefault(models.Model):\n name = models.CharField(max_length=100)\n user = models.OneToOneField(User, on_delete=models.SET_NULL, null=True)\nRun Code Online (Sandbox Code Playgroud)\n\nmyapp2/models.py:
\n\nfrom django.db import models\nfrom django.contrib.auth.models import User\n\n\nclass TestApp(models.Model):\n name = models.CharField(max_length=100)\n user = models.OneToOneField(User, on_delete=models.SET_NULL, null=True)\nRun Code Online (Sandbox Code Playgroud)\n\n迁移后,将创建这些表:
\n\nmysql(“测试”数据库):
\n\n+----------------------------+\n| Tables_in_test |\n+----------------------------+\n| auth_group |\n| auth_group_permissions |\n| auth_permission |\n| auth_user |\n| auth_user_groups |\n| auth_user_user_permissions |\n| django_admin_log |\n| django_content_type |\n| django_migrations |\n| django_session |\n| myapp2_testapp |\n+----------------------------+\nRun Code Online (Sandbox Code Playgroud)\n\npostgres(“默认”数据库):
\n\n+----------+----------------------------+--------+----------+\n| Schema | Name | Type | Owner |\n|----------+----------------------------+--------+----------|\n| public | auth_group | table | postgres |\n| public | auth_group_permissions | table | postgres |\n| public | auth_permission | table | postgres |\n| public | auth_user | table | postgres |\n| public | auth_user_groups | table | postgres |\n| public | auth_user_user_permissions | table | postgres |\n| public | django_admin_log | table | postgres |\n| public | django_content_type | table | postgres |\n| public | django_migrations | table | postgres |\n| public | django_session | table | postgres |\n| public | myapp_testdefault | table | postgres |\n+----------+----------------------------+--------+----------+\nRun Code Online (Sandbox Code Playgroud)\n\n然后我尝试在 shell 中测试关系:
\n\n+----------------------------+\n| Tables_in_test |\n+----------------------------+\n| auth_group |\n| auth_group_permissions |\n| auth_permission |\n| auth_user |\n| auth_user_groups |\n| auth_user_user_permissions |\n| django_admin_log |\n| django_content_type |\n| django_migrations |\n| django_session |\n| myapp2_testapp |\n+----------------------------+\nRun Code Online (Sandbox Code Playgroud)\n\n追溯:
\n\n---------------------------------------------------------------------------\nProgrammingError Traceback (most recent call last)\n~/projects/learn-some/learn-some-django/test/.venv/lib/python3.7/site-packages/django/db/backends/utils.py in _execute(self, sql, params, *ignored_wrapper_args)\n 83 else:\n---> 84 return self.cursor.execute(sql, params)\n 85 \n\n~/projects/learn-some/learn-some-django/test/.venv/lib/python3.7/site-packages/django/db/backends/mysql/base.py in execute(self, query, args)\n 70 # args is None means no string interpolation\n---> 71 return self.cursor.execute(query, args)\n 72 except Database.OperationalError as e:\n\n~/projects/learn-some/learn-some-django/test/.venv/lib/python3.7/site-packages/MySQLdb/cursors.py in execute(self, query, args)\n 208 assert isinstance(query, (bytes, bytearray))\n--> 209 res = self._query(query)\n 210 return res\n\n~/projects/learn-some/learn-some-django/test/.venv/lib/python3.7/site-packages/MySQLdb/cursors.py in _query(self, q)\n 314 self._result = None\n--> 315 db.query(q)\n 316 self._do_get_result(db)\n\n~/projects/learn-some/learn-some-django/test/.venv/lib/python3.7/site-packages/MySQLdb/connections.py in query(self, query)\n 225 query = bytes(query)\n--> 226 _mysql.connection.query(self, query)\n 227 \n\nProgrammingError: (1146, "Table \'test.myapp_testdefault\' doesn\'t exist")\n\nThe above exception was the direct cause of the following exception:\n\nProgrammingError Traceback (most recent call last)\n<ipython-input-22-da112720c459> in <module>\n----> 1 user.delete()\n\n~/projects/learn-some/learn-some-django/test/.venv/lib/python3.7/site-packages/django/db/models/base.py in delete(self, using, keep_parents)\n 916 \n 917 collector = Collector(using=using)\n--> 918 collector.collect([self], keep_parents=keep_parents)\n 919 return collector.delete()\n 920 \n\n~/projects/learn-some/learn-some-django/test/.venv/lib/python3.7/site-packages/django/db/models/deletion.py in collect(self, objs, source, nullable, collect_related, source_attr, reverse_dependency, keep_parents)\n 221 if self.can_fast_delete(sub_objs, from_field=field):\n 222 self.fast_deletes.append(sub_objs)\n--> 223 elif sub_objs:\n 224 field.remote_field.on_delete(self, field, sub_objs, self.using)\n 225 for field in model._meta.private_fields:\n\n~/projects/learn-some/learn-some-django/test/.venv/lib/python3.7/site-packages/django/db/models/query.py in __bool__(self)\n 276 \n 277 def __bool__(self):\n--> 278 self._fetch_all()\n 279 return bool(self._result_cache)\n 280 \n\n~/projects/learn-some/learn-some-django/test/.venv/lib/python3.7/site-packages/django/db/models/query.py in _fetch_all(self)\n 1240 def _fetch_all(self):\n 1241 if self._result_cache is None:\n-> 1242 self._result_cache = list(self._iterable_class(self))\n 1243 if self._prefetch_related_lookups and not self._prefetch_done:\n 1244 self._prefetch_related_objects()\n\n~/projects/learn-some/learn-some-django/test/.venv/lib/python3.7/site-packages/django/db/models/query.py in __iter__(self)\n 53 # Execute the query. This will also fill compiler.select, klass_info,\n 54 # and annotations.\n---> 55 results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)\n 56 select, klass_info, annotation_col_map = (compiler.select, compiler.klass_info,\n 57 compiler.annotation_col_map)\n\n~/projects/learn-some/learn-some-django/test/.venv/lib/python3.7/site-packages/django/db/models/sql/compiler.py in execute_sql(self, result_type, chunked_fetch, chunk_size)\n 1098 cursor = self.connection.cursor()\n 1099 try:\n-> 1100 cursor.execute(sql, params)\n 1101 except Exception:\n 1102 # Might fail for server-side cursors (e.g. connection closed)\n\n~/projects/learn-some/learn-some-django/test/.venv/lib/python3.7/site-packages/django/db/backends/utils.py in execute(self, sql, params)\n 97 start = time()\n 98 try:\n---> 99 return super().execute(sql, params)\n 100 finally:\n 101 stop = time()\n\n~/projects/learn-some/learn-some-django/test/.venv/lib/python3.7/site-packages/django/db/backends/utils.py in execute(self, sql, params)\n 65 \n 66 def execute(self, sql, params=None):\n---> 67 return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)\n 68 \n 69 def executemany(self, sql, param_list):\n\n~/projects/learn-some/learn-some-django/test/.venv/lib/python3.7/site-packages/django/db/backends/utils.py in _execute_with_wrappers(self, sql, params, many, executor)\n 74 for wrapper in reversed(self.db.execute_wrappers):\n 75 executor = functools.partial(wrapper, executor)\n---> 76 return executor(sql, params, many, context)\n 77 \n 78 def _execute(self, sql, params, *ignored_wrapper_args):\n\n~/projects/learn-some/learn-some-django/test/.venv/lib/python3.7/site-packages/django/db/backends/utils.py in _execute(self, sql, params, *ignored_wrapper_args)\n 82 return self.cursor.execute(sql)\n 83 else:\n---> 84 return self.cursor.execute(sql, params)\n 85 \n 86 def _executemany(self, sql, param_list, *ignored_wrapper_args):\n\n~/projects/learn-some/learn-some-django/test/.venv/lib/python3.7/site-packages/django/db/utils.py in __exit__(self, exc_type, exc_value, traceback)\n 87 if dj_exc_type not in (DataError, IntegrityError):\n 88 self.wrapper.errors_occurred = True\n---> 89 raise dj_exc_value.with_traceback(traceback) from exc_value\n 90 \n 91 def __call__(self, func):\n\n~/projects/learn-some/learn-some-django/test/.venv/lib/python3.7/site-packages/django/db/backends/utils.py in _execute(self, sql, params, *ignored_wrapper_args)\n 82 return self.cursor.execute(sql)\n 83 else:\n---> 84 return self.cursor.execute(sql, params)\n 85 \n 86 def _executemany(self, sql, param_list, *ignored_wrapper_args):\n\n~/projects/learn-some/learn-some-django/test/.venv/lib/python3.7/site-packages/django/db/backends/mysql/base.py in execute(self, query, args)\n 69 try:\n 70 # args is None means no string interpolation\n---> 71 return self.cursor.execute(query, args)\n 72 except Database.OperationalError as e:\n 73 # Map some error codes to IntegrityError, since they seem to be\n\n~/projects/learn-some/learn-some-django/test/.venv/lib/python3.7/site-packages/MySQLdb/cursors.py in execute(self, query, args)\n 207 \n 208 assert isinstance(query, (bytes, bytearray))\n--> 209 res = self._query(query)\n 210 return res\n 211 \n\n~/projects/learn-some/learn-some-django/test/.venv/lib/python3.7/site-packages/MySQLdb/cursors.py in _query(self, q)\n 313 db = self._get_db()\n 314 self._result = None\n--> 315 db.query(q)\n 316 self._do_get_result(db)\n 317 self._post_get_result()\n\n~/projects/learn-some/learn-some-django/test/.venv/lib/python3.7/site-packages/MySQLdb/connections.py in query(self, query)\n 224 if isinstance(query, bytearray):\n 225 query = bytes(query)\n--> 226 _mysql.connection.query(self, query)\n 227 \n 228 def _bytes_literal(self, bs):\n\nProgrammingError: (1146, "Table \'test.myapp_testdefault\' doesn\'t exist")\nRun Code Online (Sandbox Code Playgroud)\n\ntestdefault它表明django尝试在数据库中的表中查找记录test。显然这是不可能的。它为什么要尝试这样做?在这种情况下删除用户的正确方法是什么\xef\xbc\x9f
小智 0
using使用模型的方法删除时,可以使用参数指定要删除的数据库delete()。
这就是混乱的根源:
查询集的 delete方法不接受任何参数,如文档中所示:
对 QuerySet 中的所有行执行 SQL 删除查询,并返回已删除的对象数以及包含每种对象类型的删除数的字典。
但模型的 delete方法接受using参数:
Model.delete(using=DEFAULT_DB_ALIAS, keep_parents=False)
为对象发出 SQL DELETE。这只会删除数据库中的对象;Python 实例仍然存在,并且其字段中仍然有数据。此方法返回已删除的对象数量以及包含每种对象类型的删除数量的字典。
我希望这对那些在相同情况下感到有点困惑的人有所帮助:具有活动数据库路由器的多个数据库以及看似错误的内容被删除。
| 归档时间: |
|
| 查看次数: |
635 次 |
| 最近记录: |