Fixed #29934 -- Added sqlparse as a require dependency.
This commit is contained in:
parent
f9ff1df1da
commit
f82be9ebc7
|
@ -194,10 +194,6 @@ class BaseDatabaseFeatures:
|
|||
# Does 'a' LIKE 'A' match?
|
||||
has_case_insensitive_like = True
|
||||
|
||||
# Does the backend require the sqlparse library for splitting multi-line
|
||||
# statements before executing them?
|
||||
requires_sqlparse_for_splitting = True
|
||||
|
||||
# Suffix for backends that don't support "SELECT xxx;" queries.
|
||||
bare_select_suffix = ''
|
||||
|
||||
|
|
|
@ -2,8 +2,9 @@ import datetime
|
|||
import decimal
|
||||
from importlib import import_module
|
||||
|
||||
import sqlparse
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.db import NotSupportedError, transaction
|
||||
from django.db.backends import utils
|
||||
from django.utils import timezone
|
||||
|
@ -298,16 +299,10 @@ class BaseDatabaseOperations:
|
|||
cursor.execute() call and PEP 249 doesn't talk about this use case,
|
||||
the default implementation is conservative.
|
||||
"""
|
||||
try:
|
||||
import sqlparse
|
||||
except ImportError:
|
||||
raise ImproperlyConfigured(
|
||||
"The sqlparse package is required if you don't split your SQL "
|
||||
"statements manually."
|
||||
)
|
||||
else:
|
||||
return [sqlparse.format(statement, strip_comments=True)
|
||||
for statement in sqlparse.split(sql) if statement]
|
||||
return [
|
||||
sqlparse.format(statement, strip_comments=True)
|
||||
for statement in sqlparse.split(sql) if statement
|
||||
]
|
||||
|
||||
def process_clob(self, value):
|
||||
"""
|
||||
|
|
|
@ -26,7 +26,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
|||
nulls_order_largest = True
|
||||
closed_cursor_error_class = InterfaceError
|
||||
has_case_insensitive_like = False
|
||||
requires_sqlparse_for_splitting = False
|
||||
greatest_least_ignores_nulls = True
|
||||
can_clone_databases = True
|
||||
supports_temporal_subtraction = True
|
||||
|
|
|
@ -233,7 +233,7 @@ dependencies:
|
|||
* memcached_, plus a :ref:`supported Python binding <memcached>`
|
||||
* gettext_ (:ref:`gettext_on_windows`)
|
||||
* selenium_
|
||||
* sqlparse_
|
||||
* sqlparse_ (required)
|
||||
|
||||
You can find these dependencies in `pip requirements files`_ inside the
|
||||
``tests/requirements`` directory of the Django source tree and install them
|
||||
|
|
|
@ -240,8 +240,7 @@ partial indexes.
|
|||
|
||||
``sql``, and ``reverse_sql`` if provided, should be strings of SQL to run on
|
||||
the database. On most database backends (all but PostgreSQL), Django will
|
||||
split the SQL into individual statements prior to executing them. This
|
||||
requires installing the sqlparse_ Python library.
|
||||
split the SQL into individual statements prior to executing them.
|
||||
|
||||
You can also pass a list of strings or 2-tuples. The latter is used for passing
|
||||
queries and parameters in the same way as :ref:`cursor.execute()
|
||||
|
@ -294,8 +293,6 @@ be removed (elided) when :ref:`squashing migrations <migration-squashing>`.
|
|||
want the operation not to do anything in the given direction. This is
|
||||
especially useful in making the operation reversible.
|
||||
|
||||
.. _sqlparse: https://pypi.org/project/sqlparse/
|
||||
|
||||
``RunPython``
|
||||
-------------
|
||||
|
||||
|
|
|
@ -330,6 +330,13 @@ properly (the database was empty at the end of the whole test suite). This
|
|||
change shouldn't have an impact on your tests unless you've customized
|
||||
:class:`~django.test.TransactionTestCase`'s internals.
|
||||
|
||||
``sqlparse`` is required dependency
|
||||
-----------------------------------
|
||||
|
||||
To simplify a few parts of Django's database handling, `sqlparse
|
||||
<https://pypi.org/project/sqlparse/>`_ is now a required dependency. It's
|
||||
automatically installed along with Django.
|
||||
|
||||
Miscellaneous
|
||||
-------------
|
||||
|
||||
|
|
2
setup.py
2
setup.py
|
@ -83,7 +83,7 @@ setup(
|
|||
entry_points={'console_scripts': [
|
||||
'django-admin = django.core.management:execute_from_command_line',
|
||||
]},
|
||||
install_requires=['pytz'],
|
||||
install_requires=['pytz', 'sqlparse'],
|
||||
extras_require={
|
||||
"bcrypt": ["bcrypt"],
|
||||
"argon2": ["argon2-cffi >= 16.1.0"],
|
||||
|
|
|
@ -20,11 +20,6 @@ from .models import UnicodeModel, UnserializableModel
|
|||
from .routers import TestRouter
|
||||
from .test_base import MigrationTestBase
|
||||
|
||||
try:
|
||||
import sqlparse
|
||||
except ImportError:
|
||||
sqlparse = None
|
||||
|
||||
|
||||
class MigrateTests(MigrationTestBase):
|
||||
"""
|
||||
|
@ -355,22 +350,19 @@ class MigrateTests(MigrationTestBase):
|
|||
out.getvalue()
|
||||
)
|
||||
# Show the plan when an operation is irreversible.
|
||||
# Migration 0004's RunSQL uses a SQL string instead of a list, so
|
||||
# sqlparse may be required for splitting.
|
||||
if sqlparse or not connection.features.requires_sqlparse_for_splitting:
|
||||
# Migrate to the fourth migration.
|
||||
call_command('migrate', 'migrations', '0004', verbosity=0)
|
||||
out = io.StringIO()
|
||||
call_command('migrate', 'migrations', '0003', plan=True, stdout=out, no_color=True)
|
||||
self.assertEqual(
|
||||
'Planned operations:\n'
|
||||
'migrations.0004_fourth\n'
|
||||
' Raw SQL operation -> IRREVERSIBLE\n',
|
||||
out.getvalue()
|
||||
)
|
||||
# Cleanup by unmigrating everything: fake the irreversible, then
|
||||
# migrate all to zero.
|
||||
call_command('migrate', 'migrations', '0003', fake=True, verbosity=0)
|
||||
# Migrate to the fourth migration.
|
||||
call_command('migrate', 'migrations', '0004', verbosity=0)
|
||||
out = io.StringIO()
|
||||
call_command('migrate', 'migrations', '0003', plan=True, stdout=out, no_color=True)
|
||||
self.assertEqual(
|
||||
'Planned operations:\n'
|
||||
'migrations.0004_fourth\n'
|
||||
' Raw SQL operation -> IRREVERSIBLE\n',
|
||||
out.getvalue()
|
||||
)
|
||||
# Cleanup by unmigrating everything: fake the irreversible, then
|
||||
# migrate all to zero.
|
||||
call_command('migrate', 'migrations', '0003', fake=True, verbosity=0)
|
||||
call_command('migrate', 'migrations', 'zero', verbosity=0)
|
||||
|
||||
@override_settings(MIGRATION_MODULES={'migrations': 'migrations.test_migrations_empty'})
|
||||
|
|
|
@ -1,16 +1,9 @@
|
|||
import unittest
|
||||
|
||||
from django.db import connection, migrations, models
|
||||
from django.db.migrations.state import ProjectState
|
||||
from django.test import override_settings
|
||||
|
||||
from .test_operations import OperationTestBase
|
||||
|
||||
try:
|
||||
import sqlparse
|
||||
except ImportError:
|
||||
sqlparse = None
|
||||
|
||||
|
||||
class AgnosticRouter:
|
||||
"""
|
||||
|
@ -128,12 +121,10 @@ class MultiDBOperationTests(OperationTestBase):
|
|||
else:
|
||||
self.assertEqual(Pony.objects.count(), 0)
|
||||
|
||||
@unittest.skipIf(sqlparse is None and connection.features.requires_sqlparse_for_splitting, "Missing sqlparse")
|
||||
@override_settings(DATABASE_ROUTERS=[MigrateNothingRouter()])
|
||||
def test_run_sql(self):
|
||||
self._test_run_sql("test_mltdb_runsql", should_run=False)
|
||||
|
||||
@unittest.skipIf(sqlparse is None and connection.features.requires_sqlparse_for_splitting, "Missing sqlparse")
|
||||
@override_settings(DATABASE_ROUTERS=[MigrateWhenFooRouter()])
|
||||
def test_run_sql2(self):
|
||||
self._test_run_sql("test_mltdb_runsql2", should_run=False)
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import unittest
|
||||
|
||||
from django.core.exceptions import FieldDoesNotExist
|
||||
from django.db import connection, migrations, models, transaction
|
||||
from django.db.migrations.migration import Migration
|
||||
|
@ -14,11 +12,6 @@ from django.test import SimpleTestCase, override_settings, skipUnlessDBFeature
|
|||
from .models import FoodManager, FoodQuerySet, UnicodeModel
|
||||
from .test_base import MigrationTestBase
|
||||
|
||||
try:
|
||||
import sqlparse
|
||||
except ImportError:
|
||||
sqlparse = None
|
||||
|
||||
|
||||
class Mixin:
|
||||
pass
|
||||
|
@ -2051,7 +2044,6 @@ class OperationTests(OperationTestBase):
|
|||
self.assertColumnExists("test_afknfk_rider", "pony_id")
|
||||
self.assertColumnNotExists("test_afknfk_rider", "pony")
|
||||
|
||||
@unittest.skipIf(sqlparse is None and connection.features.requires_sqlparse_for_splitting, "Missing sqlparse")
|
||||
def test_run_sql(self):
|
||||
"""
|
||||
Tests the RunSQL operation.
|
||||
|
@ -2561,7 +2553,6 @@ class OperationTests(OperationTestBase):
|
|||
operation.database_forwards("test_runpython", editor, project_state, new_state)
|
||||
operation.database_backwards("test_runpython", editor, new_state, project_state)
|
||||
|
||||
@unittest.skipIf(sqlparse is None and connection.features.requires_sqlparse_for_splitting, "Missing sqlparse")
|
||||
def test_separate_database_and_state(self):
|
||||
"""
|
||||
Tests the SeparateDatabaseAndState operation.
|
||||
|
|
Loading…
Reference in New Issue