sqlmodel-ext 0.5.1__py3-none-any.whl → 0.5.2__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.
sqlmodel_ext/__init__.py CHANGED
@@ -20,7 +20,7 @@ Quick start::
20
20
  user = await user.save(session)
21
21
  users = await User.get(session, fetch_mode="all")
22
22
  """
23
- __version__ = "0.5.1"
23
+ __version__ = "0.5.2"
24
24
 
25
25
  # Every re-export below uses the redundant ``X as X`` form: the package ships
26
26
  # ``py.typed``, and type checkers treat a plain ``from m import X`` in a typed
sqlmodel_ext/base.py CHANGED
@@ -129,11 +129,13 @@ def _merge_field_info_attrs(target: SQLModelFieldInfo, source: FieldInfo) -> Non
129
129
  """
130
130
  Merge explicitly-set attributes from ``source`` into ``target``.
131
131
 
132
- Used when ``Annotated[Str64, Field(unique=True)]`` expands to multiple FieldInfo:
133
- ``Annotated[str, Field(max_length=64), Field(unique=True)]``, and to restore the
134
- SQLModel attributes Pydantic drops when it rebuilds ``model_fields``. A
135
- right-hand-side ``= Field(...)`` is not merged here: it follows Pydantic's
136
- resolution, ``None`` included (see ``_inherit_resolved_field``).
132
+ Only used by the metaclass's final restore step (step 7), where ``source``
133
+ is the field Pydantic built **from** ``target`` and ``target`` gets back
134
+ the values Pydantic filled in; there ``None`` never means "cleared", so
135
+ skipping it is correct. It is **not** a field-declaration merge: the
136
+ ``Field(...)`` objects of one declaration (several ``Field`` in one
137
+ ``Annotated``, an alias plus a right-hand ``= Field(...)``) follow
138
+ Pydantic's resolution, ``None`` included (see ``_inherit_resolved_field``).
137
139
  Merges attributes dynamically (via ``__slots__`` / ``__annotations__`` / ``__dict__``),
138
140
  no hardcoded attribute names — upstream additions are handled automatically.
139
141
 
@@ -205,10 +207,10 @@ def _merge_sqlmodel_metadata_carrier(
205
207
  Since sqlmodel 0.0.32, ``Field(primary_key=..., sa_type=..., ...)`` stores the
206
208
  SQLModel-specific attributes in a ``FieldInfoMetadata`` entry of
207
209
  ``metadata``, and SQLModel reads only the **first** such entry. Plain
208
- concatenation would therefore let an earlier, all-unset carrier (e.g. the
209
- one inside a constrained alias like ``NonNegativeInt``) shadow the values
210
- set by the later, more specific source (e.g. a right-hand
211
- ``= Field(primary_key=True)``).
210
+ concatenation would therefore let an earlier, all-unset carrier shadow the
211
+ values set by the later source. Only ``_merge_field_info_attrs`` (the
212
+ metaclass's restore step) uses it; the carriers of one field declaration
213
+ are folded by ``_fold_column_carriers``.
212
214
 
213
215
  Set values of the source carrier are folded into a **copy** of the target
214
216
  carrier (carriers inside type aliases are shared singletons and must not be
@@ -248,7 +250,7 @@ Public Pydantic ``FieldInfo`` attributes an inherited field takes verbatim from
248
250
 
249
251
 
250
252
  def _inherit_resolved_field(
251
- alias_fi: SQLModelFieldInfo,
253
+ alias_fis: list[SQLModelFieldInfo],
252
254
  base_fi: FieldInfo,
253
255
  annotation_metadata: list[Any],
254
256
  ) -> SQLModelFieldInfo:
@@ -256,81 +258,91 @@ def _inherit_resolved_field(
256
258
  Build the ``FieldInfo`` of a table-class field from Pydantic's resolution of its declaration.
257
259
 
258
260
  ``base_fi`` is the field as Pydantic resolves the declaration
259
- ``name: Alias = Field(...)``: the base class's entry in ``model_fields``
260
- for an inherited field, ``FieldInfo.from_annotated_attribute`` for a
261
- declaration in the table class itself. Pydantic has merged the type
262
- alias's ``Field(...)`` and the right-hand ``= Field(...)`` into it. It is
263
- the single source of truth for the field:
261
+ ``name: Alias [= value]``: the base class's entry in ``model_fields`` for
262
+ an inherited field; ``FieldInfo.from_annotated_attribute`` for a
263
+ declaration with a right-hand side (``= Field(...)`` or a plain value) in
264
+ the table class itself; ``FieldInfo.from_annotation`` for one without.
265
+ Pydantic has merged every ``Field(...)`` of the declaration into it -- the
266
+ ones inside the ``Annotated`` (later ones override earlier ones, ``None``
267
+ included) and the right-hand one (which overrides them all). ``alias_fis``
268
+ are the SQLModel ``Field(...)`` objects found in the annotation, in
269
+ declaration order. ``base_fi`` is the single source of truth for the field:
264
270
 
265
271
  - **Pydantic attributes** (``default`` / ``default_factory`` / ``alias`` /
266
272
  ``validation_alias`` / ``serialization_alias`` / ``title`` /
267
273
  ``description`` / ``examples`` / ``exclude`` / ``frozen`` / ...) are
268
274
  taken from ``base_fi`` verbatim, ``None`` included: ``Field(alias=None)``
269
- in the base clears the alias's ``alias`` and the table class must see
270
- the same field as the base does. They are passed to the constructor so
271
- that Pydantic records every one of them as explicitly set -- the same
275
+ clears an earlier ``alias`` and the table class must see the same field
276
+ as a non-table class does. They are passed to the constructor so that
277
+ Pydantic records every one of them as explicitly set -- the same
272
278
  treatment Pydantic gives a resolved ``FieldInfo`` reused as a default.
279
+ Setting them afterwards (``fi.default = value``) would not record them:
280
+ Pydantic would then drop them when it builds the field and its core
281
+ schema, while ``model_fields`` (restored by the metaclass) keeps them.
273
282
  - **Metadata** starts from ``base_fi.metadata`` minus ``annotation_metadata``:
274
283
  the metadata Pydantic collects from the rebuilt class annotation (the
275
284
  ``Annotated`` arguments other than the SQLModel ``Field``, e.g. an
276
285
  ``AfterValidator``). Pydantic adds those again when it builds the
277
286
  field, so keeping them here would run such a validator twice. Each
278
- annotation item removes one equal item. Items of ``alias_fi.metadata``
279
- whose type ``base_fi`` lacks are appended: an alias nested in a union
280
- (``Alias | None = Field(...)``) is not merged by Pydantic at field level,
281
- so its constraints (``MaxLen`` -> column length) and column carrier are
282
- absent from ``base_fi``.
287
+ annotation item removes one equal item. Items of the ``alias_fis``
288
+ metadata whose type ``base_fi`` lacks are appended: an alias nested in a
289
+ union (``Alias | None``) is not merged by Pydantic at field level, so its
290
+ constraints (``MaxLen`` -> column length) are absent from ``base_fi``.
283
291
  - **Column attributes**: SQLModel reads only the first ``FieldInfoMetadata``
284
- carrier, while ``base_fi`` holds one per ``Field(...)`` -- the right-hand
285
- one first. All carriers are folded into one (see
286
- ``_fold_column_carriers``) and the folded values are also set as
287
- instance attributes for readers using ``getattr(field, 'primary_key')``.
288
-
289
- ``alias_fi`` is not mutated.
292
+ carrier. All carriers of the declaration are folded into one (see
293
+ ``_fold_column_carriers``), by the precedence Pydantic applies to the
294
+ Pydantic attributes: the carriers of ``base_fi`` that are not the
295
+ annotation's (those of the right-hand ``Field``) first, then the
296
+ annotation's from the last ``Field`` to the first. The folded values
297
+ are also set as instance attributes for readers using
298
+ ``getattr(field, 'primary_key')``.
299
+
300
+ Neither ``alias_fis`` nor their carriers are mutated.
290
301
  """
291
302
  kwargs: dict[str, Any] = {name: getattr(base_fi, name) for name in _PYDANTIC_FIELD_ATTRS}
292
303
  inherited = SQLModelFieldInfo(**kwargs)
293
304
 
305
+ alias_meta = [item for alias_fi in alias_fis for item in alias_fi.metadata]
306
+ alias_carriers = [item for item in alias_meta if isinstance(item, FieldInfoMetadata)]
307
+ base_types = {type(item) for item in base_fi.metadata}
294
308
  base_meta = list(base_fi.metadata)
295
309
  for item in annotation_metadata:
296
310
  base_meta.remove(item)
297
- base_types = {type(item) for item in base_meta}
298
- alias_extra = [
299
- item for item in alias_fi.metadata
300
- if isinstance(item, FieldInfoMetadata) or type(item) not in base_types
311
+ right_hand_carriers = [
312
+ item for item in base_meta
313
+ if isinstance(item, FieldInfoMetadata) and not any(item is c for c in alias_carriers)
301
314
  ]
302
- metadata = _fold_column_carriers(base_meta + alias_extra)
303
- inherited.metadata = metadata
304
-
305
- carrier = next((m for m in metadata if isinstance(m, FieldInfoMetadata)), None)
315
+ metadata = [item for item in base_meta if not isinstance(item, FieldInfoMetadata)]
316
+ metadata += [
317
+ item for item in alias_meta
318
+ if not isinstance(item, FieldInfoMetadata) and type(item) not in base_types
319
+ ]
320
+ carrier = _fold_column_carriers(right_hand_carriers + alias_carriers[::-1])
306
321
  if carrier is not None:
322
+ metadata.append(carrier)
307
323
  for fim_field in dataclasses.fields(carrier):
308
324
  value = getattr(carrier, fim_field.name)
309
325
  if value is not _FIM_UNSET_SA_TYPE:
310
326
  setattr(inherited, fim_field.name, value)
327
+ inherited.metadata = metadata
311
328
  return inherited
312
329
 
313
330
 
314
- def _fold_column_carriers(metadata: list[Any]) -> list[Any]:
331
+ def _fold_column_carriers(carriers: list[FieldInfoMetadata]) -> FieldInfoMetadata | None:
315
332
  """
316
- Fold every ``FieldInfoMetadata`` carrier of ``metadata`` into the first one.
317
-
318
- Carriers are ordered by precedence: an earlier carrier's set value wins; a
319
- later carrier only fills attributes the earlier ones left unset -- except
320
- that ``True`` replaces an earlier ``False`` (the rule
321
- ``_merge_field_info_attrs`` applies to boolean flags, so ``unique=False`` on
322
- the right-hand side never switches off ``unique=True`` from the alias).
323
- The first carrier is replaced by a folded **copy** (carriers inside type
324
- aliases are shared); the others are dropped. Non-carrier items are kept
325
- unchanged and in order.
333
+ Fold ``FieldInfoMetadata`` carriers, ordered by precedence, into a new one.
334
+
335
+ An earlier carrier's set value wins; a later carrier only fills attributes
336
+ the earlier ones left unset -- except that ``True`` replaces an earlier
337
+ ``False``, so ``unique=False`` never switches off ``unique=True`` set
338
+ elsewhere in the declaration. The result is always a **copy** (carriers
339
+ inside type aliases are shared singletons and are later written to, e.g.
340
+ by ``_durably_set_sa_type``). ``None`` when there is no carrier.
326
341
  """
327
- carrier_indexes = [i for i, m in enumerate(metadata) if isinstance(m, FieldInfoMetadata)]
328
- if len(carrier_indexes) < 2:
329
- return list(metadata)
330
- first = carrier_indexes[0]
331
- folded = copy.copy(metadata[first])
332
- for index in carrier_indexes[1:]:
333
- later = metadata[index]
342
+ if not carriers:
343
+ return None
344
+ folded = copy.copy(carriers[0])
345
+ for later in carriers[1:]:
334
346
  for fim_field in dataclasses.fields(later):
335
347
  value = getattr(later, fim_field.name)
336
348
  if value is _FIM_UNSET_SA_TYPE:
@@ -338,49 +350,46 @@ def _fold_column_carriers(metadata: list[Any]) -> list[Any]:
338
350
  current = getattr(folded, fim_field.name)
339
351
  if current is _FIM_UNSET_SA_TYPE or (current is False and value is True):
340
352
  setattr(folded, fim_field.name, value)
341
- dropped = frozenset(carrier_indexes[1:])
342
- return [folded if i == first else m for i, m in enumerate(metadata) if i not in dropped]
353
+ return folded
343
354
 
344
355
 
345
356
  def _find_field_info_in_annotated(annotation: Any) -> SQLModelFieldInfo | None:
346
357
  """
347
- Extract SQLModel ``FieldInfo`` embedded in ``Annotated[T, Field(...)]`` metadata.
358
+ Build a right-hand ``Field`` for ``Annotated[T, Field(...)]`` that changes nothing Pydantic resolves.
348
359
 
349
360
  Used by the metaclass sa_type injection loop. When a field is declared
350
361
  ``Annotated[X, Field(default_factory=list, ...)]`` *without* an explicit
351
362
  ``= ...`` assignment, ``attrs[field_name]`` is ``Undefined``. Replacing
352
363
  it with a fresh ``Field(sa_type=sa_type)`` would discard the user's
353
364
  Field metadata (``default_factory``, ``max_length``, validators, ...)
354
- that lives inside the Annotated args. This helper recovers that
355
- FieldInfo so the caller can attach ``sa_type`` to the user's Field
356
- instead of clobbering it. The bug only surfaces after 2+ levels of
357
- inheritance: single-class instantiation goes through Pydantic's native
358
- Annotated path and works, but child classes rebuild ``model_fields``
359
- from the clobbered ``attrs`` and the field becomes silently
360
- ``is_required=True``.
361
-
362
- Multiple FieldInfo args (e.g. ``Annotated[Str64, Field(unique=True)]``
363
- expands to ``Annotated[str, Field(max_length=64), Field(unique=True)]``)
364
- are merged into a single shallow copy so the shared Annotated metadata
365
- singletons are never mutated.
365
+ that lives inside the Annotated args. The bug only surfaces after 2+
366
+ levels of inheritance: single-class instantiation goes through
367
+ Pydantic's native Annotated path and works, but child classes rebuild
368
+ ``model_fields`` from the clobbered ``attrs`` and the field becomes
369
+ silently ``is_required=True``.
370
+
371
+ The returned field carries Pydantic's own resolution of the annotation
372
+ (every ``Field`` in it merged, later ones overriding earlier ones,
373
+ ``None`` included) with every Pydantic attribute explicitly set, so
374
+ Pydantic, merging it back in as the right-hand side, gets the same field
375
+ as without it. Its only metadata is the folded column carrier, to which
376
+ the caller attaches ``sa_type``; the annotation's constraints stay in the
377
+ annotation. Reached for non-table classes only: a table class's
378
+ annotation has already been stripped of its SQLModel ``Field``s by
379
+ ``_recover_annotated_sqlmodel_fields``.
366
380
 
367
381
  :param annotation: Field type annotation
368
- :returns: Merged SQLModelFieldInfo (shallow copy, safe to mutate), or None
382
+ :returns: A new SQLModelFieldInfo (safe to mutate), or None
369
383
  """
370
384
  if get_origin(annotation) is not typing.Annotated:
371
385
  return None
372
- args = get_args(annotation)
373
- if len(args) < 2:
374
- return None
375
386
  sqlmodel_fis: list[SQLModelFieldInfo] = [
376
- arg for arg in args[1:] if isinstance(arg, SQLModelFieldInfo)
387
+ arg for arg in get_args(annotation)[1:] if isinstance(arg, SQLModelFieldInfo)
377
388
  ]
378
389
  if not sqlmodel_fis:
379
390
  return None
380
- merged = copy.copy(sqlmodel_fis[0])
381
- for extra_fi in sqlmodel_fis[1:]:
382
- _merge_field_info_attrs(merged, extra_fi)
383
- return merged
391
+ resolved = FieldInfo.from_annotation(annotation)
392
+ return _inherit_resolved_field(sqlmodel_fis, resolved, list(resolved.metadata))
384
393
 
385
394
 
386
395
  def _durably_set_sa_type(field_info: Any, sa_type: Any) -> None:
@@ -835,12 +844,6 @@ def _recover_annotated_sqlmodel_fields(
835
844
  if not sqlmodel_fis:
836
845
  continue
837
846
 
838
- # Merge multiple FieldInfo: shallow-copy first then merge to avoid mutating
839
- # shared Annotated metadata singletons (e.g. Str64 = Annotated[str, Field(max_length=64)])
840
- sqlmodel_fi = copy.copy(sqlmodel_fis[0])
841
- for extra_fi in sqlmodel_fis[1:]:
842
- _merge_field_info_attrs(sqlmodel_fi, extra_fi)
843
-
844
847
  # The class annotation without the SQLModel FieldInfo; any other
845
848
  # ``Annotated`` metadata (validators, serializers, ...) stays in it.
846
849
  base_type = args[0]
@@ -864,62 +867,48 @@ def _recover_annotated_sqlmodel_fields(
864
867
  else:
865
868
  rebuilt = new_inner
866
869
 
867
- # Transfer plain defaults from attrs (e.g. = 0, = None) to FieldInfo
870
+ # The field is rebuilt from Pydantic's resolution of the declaration --
871
+ # the same ``FieldInfo`` a non-table class gets for it (see
872
+ # ``_inherit_resolved_field``): its Pydantic attributes follow that
873
+ # resolution, ``None`` included; only the column attributes of every
874
+ # ``Field`` of the declaration are folded together.
868
875
  existing_default = attrs.get(field_name, Undefined)
869
- if existing_default is not Undefined and not isinstance(existing_default, (FieldInfo, SQLModelFieldInfo)):
870
- sqlmodel_fi.default = existing_default
871
- elif isinstance(existing_default, (FieldInfo, SQLModelFieldInfo)):
872
- # A right-hand-side ``= Field(...)`` coexists with the FieldInfo inside
873
- # the annotation, e.g.
874
- # ``value: NonNegativeBigInt | None = Field(default=None, sa_type=BigInteger)``.
875
- # Without this branch the right-hand FieldInfo would be discarded
876
- # (overwritten by ``attrs[field_name] = sqlmodel_fi`` below) and an
877
- # explicit ``default=None`` would vanish, silently making the field
878
- # required.
879
- #
880
- # Pydantic resolves the declaration exactly as it does for a
881
- # non-table class (``from_annotated_attribute`` is the step that
882
- # builds ``model_fields`` entries), so the field is then treated like
883
- # an inherited one: its Pydantic attributes follow that resolution,
884
- # ``None`` included (``Field(alias=None)`` clears the alias's
885
- # ``alias``, as in plain SQLModel and in a table class inheriting
886
- # the same declaration); only the column attributes of the alias
887
- # and the right-hand ``Field`` are folded together (see
888
- # ``_inherit_resolved_field``).
876
+ base_fi = next(
877
+ (
878
+ base_fields[field_name]
879
+ for base in bases
880
+ if (base_fields := getattr(base, 'model_fields', None)) and field_name in base_fields
881
+ ),
882
+ None,
883
+ )
884
+ if existing_default is not Undefined:
885
+ # A right-hand side in the class body: ``= Field(...)`` or a plain
886
+ # value (``= 0``, ``= None``). ``from_annotated_attribute`` is the
887
+ # step Pydantic uses to build ``model_fields`` entries.
889
888
  resolved = FieldInfo.from_annotated_attribute(field_type, existing_default)
890
- sqlmodel_fi = _inherit_resolved_field(
891
- sqlmodel_fi, resolved, FieldInfo.from_annotation(rebuilt).metadata,
892
- )
893
- elif existing_default is Undefined:
894
- base_fi = next(
895
- (
896
- base_fields[field_name]
897
- for base in bases
898
- if (base_fields := getattr(base, 'model_fields', None)) and field_name in base_fields
899
- ),
900
- None,
901
- )
902
- if base_fi is not None and field_name not in own_names:
903
- # An inherited field (the class body does not declare it). Its
904
- # right-hand ``= Field(...)`` lives in the base class, not in
905
- # ``attrs``; without this branch the injected
906
- # ``attrs[field_name]`` replaces the inherited field with the
907
- # alias's ``Field`` alone, and a column declared
908
- # ``Field(index=True)`` in a base class loses its index.
909
- sqlmodel_fi = _inherit_resolved_field(
910
- sqlmodel_fi, base_fi, FieldInfo.from_annotation(rebuilt).metadata,
911
- )
912
- elif (
889
+ elif base_fi is not None and field_name not in own_names:
890
+ # An inherited field (the class body does not declare it). Its
891
+ # right-hand side lives in the base class, not in ``attrs``: the
892
+ # base's resolved field is the declaration's resolution. Without it
893
+ # a column declared ``Field(index=True)`` in a base class loses its
894
+ # index.
895
+ resolved = base_fi
896
+ else:
897
+ resolved = FieldInfo.from_annotation(field_type)
898
+ if (
913
899
  base_fi is not None
914
- and sqlmodel_fi.default is Undefined
915
- and sqlmodel_fi.default_factory is None
900
+ and resolved.default is Undefined
901
+ and resolved.default_factory is None
916
902
  ):
917
903
  # Re-declared in the class body without a right-hand side:
918
- # only the default is inherited.
904
+ # the base's default is inherited.
919
905
  if base_fi.default is not Undefined:
920
- sqlmodel_fi.default = base_fi.default
906
+ resolved.default = base_fi.default
921
907
  elif base_fi.default_factory is not None:
922
- sqlmodel_fi.default_factory = base_fi.default_factory
908
+ resolved.default_factory = base_fi.default_factory
909
+ sqlmodel_fi = _inherit_resolved_field(
910
+ sqlmodel_fis, resolved, FieldInfo.from_annotation(rebuilt).metadata,
911
+ )
923
912
 
924
913
  # Inject SQLModel FieldInfo as field default (equivalent to = Field(...) style)
925
914
  attrs[field_name] = sqlmodel_fi
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: sqlmodel-ext
3
- Version: 0.5.1
3
+ Version: 0.5.2
4
4
  Summary: Extended SQLModel infrastructure: smart metaclass, async CRUD mixins, polymorphic inheritance, optimistic locking, relation preloading, and reusable field types.
5
5
  Project-URL: Homepage, https://github.com/Foxerine/sqlmodel-ext
6
6
  Project-URL: Repository, https://github.com/Foxerine/sqlmodel-ext
@@ -1,10 +1,10 @@
1
- sqlmodel_ext/__init__.py,sha256=m2pRpqWuPhhX4E_Tc-qlZESnrpzyZf_ykOhhvBZOd0Y,9632
1
+ sqlmodel_ext/__init__.py,sha256=6d8M5DatC9eLiPSyFxoZh0GpXatZNgHIOkpHzIgxyOo,9632
2
2
  sqlmodel_ext/_compat.py,sha256=KMLFLQE88J605lSg9bYOUusFjrl46jZKI5VW8C_mNbI,12392
3
3
  sqlmodel_ext/_exceptions.py,sha256=CgowpnaxrbQ0EVOfoEJTSrWcJww5AsYMq2AhqzjLTkA,418
4
4
  sqlmodel_ext/_sa_type.py,sha256=ZV6Ag_QoyNrGnlf0SLekIpi7Dww07euiU5K4Q9mCbgc,5382
5
5
  sqlmodel_ext/_type_unwrap.py,sha256=J13pqE-AMzf9fvL6gucQdPXz6Fy702daMICHVDzB2tw,4718
6
6
  sqlmodel_ext/_utils.py,sha256=cFrlQp1Uq-4ZAdvi_u79UbEI0IHZaAm5VkXadCXrBmI,174
7
- sqlmodel_ext/base.py,sha256=5Do-HZztQ7SDuGbbb--GDQWhpGPB68au7BnSha5JF2I,106335
7
+ sqlmodel_ext/base.py,sha256=q2cLy-RrIr090_HOA8zZDUFceasXnVHjCyCn4_uzgqk,105996
8
8
  sqlmodel_ext/check_derived.py,sha256=cbsX7qbYaYvD1awYXIULDa7eUbQusYCc6Id76Uey-vI,25069
9
9
  sqlmodel_ext/constants.py,sha256=O_1wteUx3-F4yydBIsITUf4oyjzgbtUuzjlDkrybsF4,3657
10
10
  sqlmodel_ext/dependencies.py,sha256=T_oX2S4AyCRgMPTT_wCzsaib_n1QquzpUjz3Hn3t0TU,9387
@@ -43,8 +43,8 @@ sqlmodel_ext/mixins/relation_preload.py,sha256=hjIMTn1CitUQ27lkSC15CTsMdXdF5bF4q
43
43
  sqlmodel_ext/mixins/resource_quota.py,sha256=n9apvZsC4LfbfVjVp9I4q4s2_yBNlSaCYdo12DelQ2A,13860
44
44
  sqlmodel_ext/mixins/table.py,sha256=tFXc2ygoX4jdeTR1tRCCtQ7ioF2DQZQxLMfJ1j1Qc30,99825
45
45
  sqlmodel_ext/mixins/trgm_searchable.py,sha256=UbxGCYrhotJc5P0HC5igd-_OPY6cc0Gr8QNnMXYl4Qg,11091
46
- sqlmodel_ext-0.5.1.dist-info/METADATA,sha256=79TveVRdP_DdvlYG5Cuz9mmTnzGgkNVvgSq90zXvmSo,82118
47
- sqlmodel_ext-0.5.1.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
48
- sqlmodel_ext-0.5.1.dist-info/entry_points.txt,sha256=nQMADgM0kg5c7Nt3ynaStu5Zzkq1SNhNrtl286JjbrA,79
49
- sqlmodel_ext-0.5.1.dist-info/licenses/LICENSE,sha256=8ek0ENxpcXcIhCC7MXetxiYLKflHqz2JbA-nwDqTsyI,1088
50
- sqlmodel_ext-0.5.1.dist-info/RECORD,,
46
+ sqlmodel_ext-0.5.2.dist-info/METADATA,sha256=7pX2YB1vMaLJeXZSIoTEoLSZbfu6Nfkgy9iHy3sgcPE,82118
47
+ sqlmodel_ext-0.5.2.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
48
+ sqlmodel_ext-0.5.2.dist-info/entry_points.txt,sha256=nQMADgM0kg5c7Nt3ynaStu5Zzkq1SNhNrtl286JjbrA,79
49
+ sqlmodel_ext-0.5.2.dist-info/licenses/LICENSE,sha256=8ek0ENxpcXcIhCC7MXetxiYLKflHqz2JbA-nwDqTsyI,1088
50
+ sqlmodel_ext-0.5.2.dist-info/RECORD,,