plain.models 0.34.4__py3-none-any.whl → 0.35.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- plain/models/CHANGELOG.md +11 -0
- plain/models/backends/mysql/base.py +5 -48
- plain/models/backends/mysql/schema.py +3 -1
- plain/models/cli.py +31 -0
- {plain_models-0.34.4.dist-info → plain_models-0.35.0.dist-info}/METADATA +1 -1
- {plain_models-0.34.4.dist-info → plain_models-0.35.0.dist-info}/RECORD +9 -9
- {plain_models-0.34.4.dist-info → plain_models-0.35.0.dist-info}/WHEEL +0 -0
- {plain_models-0.34.4.dist-info → plain_models-0.35.0.dist-info}/entry_points.txt +0 -0
- {plain_models-0.34.4.dist-info → plain_models-0.35.0.dist-info}/licenses/LICENSE +0 -0
plain/models/CHANGELOG.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
# plain-models changelog
|
2
2
|
|
3
|
+
## [0.35.0](https://github.com/dropseed/plain/releases/plain-models@0.35.0) (2025-07-07)
|
4
|
+
|
5
|
+
### What's changed
|
6
|
+
|
7
|
+
- Added the `plain models list` CLI command which prints a nicely formatted list of all installed models, including their table name, fields, and originating package. You can pass package labels to filter the output or use the `--app-only` flag to only show first-party app models ([1bc40ce](https://github.com/dropseed/plain/commit/1bc40ce)).
|
8
|
+
- The MySQL backend no longer enforces a strict `mysqlclient >= 1.4.3` version check and had several unused constraint-handling methods removed, reducing boilerplate and improving compatibility with a wider range of `mysqlclient` versions ([6322400](https://github.com/dropseed/plain/commit/6322400), [67f21f6](https://github.com/dropseed/plain/commit/67f21f6)).
|
9
|
+
|
10
|
+
### Upgrade instructions
|
11
|
+
|
12
|
+
- No changes required
|
13
|
+
|
3
14
|
## [0.34.4](https://github.com/dropseed/plain/releases/plain-models@0.34.4) (2025-07-02)
|
4
15
|
|
5
16
|
### What's changed
|
@@ -6,23 +6,16 @@ Requires mysqlclient: https://pypi.org/project/mysqlclient/
|
|
6
6
|
|
7
7
|
from functools import cached_property
|
8
8
|
|
9
|
+
import MySQLdb as Database
|
10
|
+
from MySQLdb.constants import CLIENT, FIELD_TYPE
|
11
|
+
from MySQLdb.converters import conversions
|
12
|
+
|
9
13
|
from plain.exceptions import ImproperlyConfigured
|
10
14
|
from plain.models.backends import utils as backend_utils
|
11
15
|
from plain.models.backends.base.base import BaseDatabaseWrapper
|
12
16
|
from plain.models.db import IntegrityError
|
13
17
|
from plain.utils.regex_helper import _lazy_re_compile
|
14
18
|
|
15
|
-
try:
|
16
|
-
import MySQLdb as Database
|
17
|
-
except ImportError as err:
|
18
|
-
raise ImproperlyConfigured(
|
19
|
-
"Error loading MySQLdb module.\nDid you install mysqlclient?"
|
20
|
-
) from err
|
21
|
-
|
22
|
-
from MySQLdb.constants import CLIENT, FIELD_TYPE
|
23
|
-
from MySQLdb.converters import conversions
|
24
|
-
|
25
|
-
# Some of these import MySQLdb, so import them after checking if it's installed.
|
26
19
|
from .client import DatabaseClient
|
27
20
|
from .creation import DatabaseCreation
|
28
21
|
from .features import DatabaseFeatures
|
@@ -31,13 +24,6 @@ from .operations import DatabaseOperations
|
|
31
24
|
from .schema import DatabaseSchemaEditor
|
32
25
|
from .validation import DatabaseValidation
|
33
26
|
|
34
|
-
version = Database.version_info
|
35
|
-
if version < (1, 4, 3):
|
36
|
-
raise ImproperlyConfigured(
|
37
|
-
f"mysqlclient 1.4.3 or newer is required; you have {Database.__version__}."
|
38
|
-
)
|
39
|
-
|
40
|
-
|
41
27
|
# MySQLdb returns TIME columns as timedelta -- they are more like timedelta in
|
42
28
|
# terms of actual behavior as they are signed and include days -- and Plain
|
43
29
|
# expects time.
|
@@ -281,37 +267,8 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
|
281
267
|
with self.wrap_database_errors:
|
282
268
|
self.connection.autocommit(autocommit)
|
283
269
|
|
284
|
-
def disable_constraint_checking(self):
|
285
|
-
"""
|
286
|
-
Disable foreign key checks, primarily for use in adding rows with
|
287
|
-
forward references. Always return True to indicate constraint checks
|
288
|
-
need to be re-enabled.
|
289
|
-
"""
|
290
|
-
with self.cursor() as cursor:
|
291
|
-
cursor.execute("SET foreign_key_checks=0")
|
292
|
-
return True
|
293
|
-
|
294
|
-
def enable_constraint_checking(self):
|
295
|
-
"""
|
296
|
-
Re-enable foreign key checks after they have been disabled.
|
297
|
-
"""
|
298
|
-
# Override needs_rollback in case constraint_checks_disabled is
|
299
|
-
# nested inside transaction.atomic.
|
300
|
-
self.needs_rollback, needs_rollback = False, self.needs_rollback
|
301
|
-
try:
|
302
|
-
with self.cursor() as cursor:
|
303
|
-
cursor.execute("SET foreign_key_checks=1")
|
304
|
-
finally:
|
305
|
-
self.needs_rollback = needs_rollback
|
306
|
-
|
307
270
|
def check_constraints(self, table_names=None):
|
308
|
-
"""
|
309
|
-
Check each table name in `table_names` for rows with invalid foreign
|
310
|
-
key references. This method is intended to be used in conjunction with
|
311
|
-
`disable_constraint_checking()` and `enable_constraint_checking()`, to
|
312
|
-
determine if rows with invalid references were entered while constraint
|
313
|
-
checks were off.
|
314
|
-
"""
|
271
|
+
"""Check ``table_names`` for rows with invalid foreign key references."""
|
315
272
|
with self.cursor() as cursor:
|
316
273
|
if table_names is None:
|
317
274
|
table_names = self.introspection.table_names(cursor)
|
@@ -1,6 +1,8 @@
|
|
1
1
|
from plain.models.backends.base.schema import BaseDatabaseSchemaEditor
|
2
2
|
from plain.models.constants import LOOKUP_SEP
|
3
|
-
from plain.models.
|
3
|
+
from plain.models.constraints import UniqueConstraint
|
4
|
+
from plain.models.expressions import F
|
5
|
+
from plain.models.fields import NOT_PROVIDED
|
4
6
|
|
5
7
|
|
6
8
|
class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
|
plain/models/cli.py
CHANGED
@@ -96,6 +96,37 @@ def db_wait():
|
|
96
96
|
break
|
97
97
|
|
98
98
|
|
99
|
+
@cli.command(name="list")
|
100
|
+
@click.argument("package_labels", nargs=-1)
|
101
|
+
@click.option(
|
102
|
+
"--app-only",
|
103
|
+
is_flag=True,
|
104
|
+
help="Only show models from packages that start with 'app'.",
|
105
|
+
)
|
106
|
+
def list_models(package_labels, app_only):
|
107
|
+
"""List installed models."""
|
108
|
+
|
109
|
+
packages = set(package_labels)
|
110
|
+
|
111
|
+
for model in sorted(
|
112
|
+
models_registry.get_models(),
|
113
|
+
key=lambda m: (m._meta.package_label, m._meta.model_name),
|
114
|
+
):
|
115
|
+
pkg = model._meta.package_label
|
116
|
+
pkg_name = packages_registry.get_package_config(pkg).name
|
117
|
+
if app_only and not pkg_name.startswith("app"):
|
118
|
+
continue
|
119
|
+
if packages and pkg not in packages:
|
120
|
+
continue
|
121
|
+
fields = ", ".join(f.name for f in model._meta.get_fields())
|
122
|
+
click.echo(
|
123
|
+
f"{click.style(pkg, fg='cyan')}.{click.style(model.__name__, fg='blue')}"
|
124
|
+
)
|
125
|
+
click.echo(f" table: {model._meta.db_table}")
|
126
|
+
click.echo(f" fields: {fields}")
|
127
|
+
click.echo(f" package: {pkg_name}\n")
|
128
|
+
|
129
|
+
|
99
130
|
@register_cli("makemigrations")
|
100
131
|
@cli.command()
|
101
132
|
@click.argument("package_labels", nargs=-1)
|
@@ -1,9 +1,9 @@
|
|
1
|
-
plain/models/CHANGELOG.md,sha256=
|
1
|
+
plain/models/CHANGELOG.md,sha256=bUinpgx_HxNjgItauzHyszRtwU7F3Zm33u0mMAZBoDs,4127
|
2
2
|
plain/models/README.md,sha256=vsZPev3Fna-Irdcs3-wrOcAoII5LOhXdcWLBMT87CS0,1626
|
3
3
|
plain/models/__init__.py,sha256=dnU6MOXs3lGoK31nLWjCqbf7zigkaUccomchz9lNDJ8,2950
|
4
4
|
plain/models/aggregates.py,sha256=P0mhsMl1VZt2CVHMuCHnNI8SxZ9citjDLEgioN6NOpo,7240
|
5
5
|
plain/models/base.py,sha256=8-F9DvSF5s2_zoGyEmZU5xg9GdEigthVT0HENv9iigI,67952
|
6
|
-
plain/models/cli.py,sha256
|
6
|
+
plain/models/cli.py,sha256=4iZRHRPXxUCrsW-SzeimIE_lrSkWkLhgYOSk4BxUF_8,44985
|
7
7
|
plain/models/config.py,sha256=OF7eIEtXNZyGwgc3eMEpb5uEAup5RXeT-0um60dfBeU,636
|
8
8
|
plain/models/connections.py,sha256=RBNa2FZ0x3C9un6PaYL-IYzH_OesRSpdHNGKvYHGiOM,2276
|
9
9
|
plain/models/constants.py,sha256=ndnj9TOTKW0p4YcIPLOLEbsH6mOgFi6B1-rIzr_iwwU,210
|
@@ -40,14 +40,14 @@ plain/models/backends/base/operations.py,sha256=Y08cS7IZwYXMKVUoEpBCjyOTh1PW2OSh
|
|
40
40
|
plain/models/backends/base/schema.py,sha256=1dLiVNz1huv8xJo1JphgfWfhXXZ-YGw_MgZ6eWazKQA,65016
|
41
41
|
plain/models/backends/base/validation.py,sha256=2zpI11hyUJr0I0cA1xmvoFwQVdZ-7_1T2F11TpQ0Rkk,1067
|
42
42
|
plain/models/backends/mysql/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
43
|
-
plain/models/backends/mysql/base.py,sha256=
|
43
|
+
plain/models/backends/mysql/base.py,sha256=BfFi7QipjpW38LJquRINdUnm6cIBKEDVgiApMuWo1OQ,14421
|
44
44
|
plain/models/backends/mysql/client.py,sha256=YGjk4f5VOuIKcj5SOOJeBqiSDF0Ft9m1aUPOmLzdD6c,2973
|
45
45
|
plain/models/backends/mysql/compiler.py,sha256=NaYgcGyFUZ2lTOXXJj87hLMMMnXRAS1jUYkJq1NoCv4,3289
|
46
46
|
plain/models/backends/mysql/creation.py,sha256=ozuc3mz65bjFz6sn5BFLRRGQsUYaxwIGjQyKod31c1Y,952
|
47
47
|
plain/models/backends/mysql/features.py,sha256=OPHaiqPmAFAUZqnZdLOqbCmxmuGMnIqa62fJqAkYQ0o,5875
|
48
48
|
plain/models/backends/mysql/introspection.py,sha256=nKhuFDi8xxj0DZH8_45F-XOARiHxWBoW21_2lTFARUc,14131
|
49
49
|
plain/models/backends/mysql/operations.py,sha256=zLtg50k7WzqO3eZjLAknhKg29bxm0-ysd1_NydlDlzQ,16665
|
50
|
-
plain/models/backends/mysql/schema.py,sha256=
|
50
|
+
plain/models/backends/mysql/schema.py,sha256=LmP62COVuhpbH4gYulcSQNJgGuolc3RTFGsudoohJOQ,9942
|
51
51
|
plain/models/backends/mysql/validation.py,sha256=TFYpuRoy3yG3SGfMFtRewaWq5gISN6FBaq-AD0DY7SI,1946
|
52
52
|
plain/models/backends/postgresql/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
53
53
|
plain/models/backends/postgresql/base.py,sha256=SE6wmmxOtCnMDwycUs9yn_WATl97eV-4t8AaiK41E20,16053
|
@@ -113,8 +113,8 @@ plain/models/sql/where.py,sha256=ezE9Clt2BmKo-I7ARsgqZ_aVA-1UdayCwr6ULSWZL6c,126
|
|
113
113
|
plain/models/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
114
114
|
plain/models/test/pytest.py,sha256=5mxY1MHqfCFJ7G39W1DuE0vCHfsfehQQmOyE6vI6caw,3323
|
115
115
|
plain/models/test/utils.py,sha256=MxBNWoGMtwAtka7LbxWgilgzv7T5qqJL8ystF2SDJrs,345
|
116
|
-
plain_models-0.
|
117
|
-
plain_models-0.
|
118
|
-
plain_models-0.
|
119
|
-
plain_models-0.
|
120
|
-
plain_models-0.
|
116
|
+
plain_models-0.35.0.dist-info/METADATA,sha256=v8A_EGrAuBGpAa_7thYuC1eim5Alt7jdfLskHWfUerg,1921
|
117
|
+
plain_models-0.35.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
118
|
+
plain_models-0.35.0.dist-info/entry_points.txt,sha256=IYJAW9MpL3PXyXFWmKmALagAGXC_5rzBn2eEGJlcV04,112
|
119
|
+
plain_models-0.35.0.dist-info/licenses/LICENSE,sha256=m0D5O7QoH9l5Vz_rrX_9r-C8d9UNr_ciK6Qwac7o6yo,3175
|
120
|
+
plain_models-0.35.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|