sqlobjects 1.0.3__tar.gz → 1.0.4__tar.gz
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.
- {sqlobjects-1.0.3/sqlobjects.egg-info → sqlobjects-1.0.4}/PKG-INFO +1 -1
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/pyproject.toml +1 -1
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/mixins.py +49 -1
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/model.py +71 -70
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/objects/bulk.py +10 -13
- {sqlobjects-1.0.3 → sqlobjects-1.0.4/sqlobjects.egg-info}/PKG-INFO +1 -1
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/LICENSE +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/README.md +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/setup.cfg +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/__init__.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/cascade.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/database/__init__.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/database/config.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/database/manager.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/exceptions.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/expressions/__init__.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/expressions/aggregate.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/expressions/base.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/expressions/function.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/expressions/mixins.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/expressions/scalar.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/expressions/subquery.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/expressions/terminal.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/fields/__init__.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/fields/core.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/fields/functions.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/fields/proxies.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/fields/relations/__init__.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/fields/relations/descriptors.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/fields/relations/managers.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/fields/relations/proxies.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/fields/relations/utils.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/fields/shortcuts.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/fields/types/__init__.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/fields/types/base.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/fields/types/comparators.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/fields/types/registry.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/fields/utils.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/metadata.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/objects/__init__.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/objects/core.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/queries/__init__.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/queries/builder.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/queries/executor.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/queryset.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/session.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/signals.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/utils/__init__.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/utils/inspect.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/utils/naming.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/utils/pattern.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects/validators.py +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects.egg-info/SOURCES.txt +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects.egg-info/dependency_links.txt +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects.egg-info/requires.txt +0 -0
- {sqlobjects-1.0.3 → sqlobjects-1.0.4}/sqlobjects.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sqlobjects
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.4
|
|
4
4
|
Summary: Django-style async ORM library based on SQLAlchemy with chainable queries, Q objects, and relationship loading
|
|
5
5
|
Author-email: XtraVisions <gitadmin@xtravisions.com>, Chen Hao <chenhao@xtravisions.com>
|
|
6
6
|
Maintainer-email: XtraVisions <gitadmin@xtravisions.com>, Chen Hao <chenhao@xtravisions.com>
|
|
@@ -417,7 +417,7 @@ class DataConversionMixin(DeferredLoadingMixin):
|
|
|
417
417
|
for field_name, value in non_init_data.items():
|
|
418
418
|
# Apply default value if value is None
|
|
419
419
|
if value is None:
|
|
420
|
-
default_value = instance._get_field_default_value(field_name) # noqa
|
|
420
|
+
default_value = instance._get_field_default_value(field_name) # noqa
|
|
421
421
|
if default_value is not None:
|
|
422
422
|
value = default_value
|
|
423
423
|
setattr(instance, field_name, value)
|
|
@@ -432,6 +432,46 @@ class DataConversionMixin(DeferredLoadingMixin):
|
|
|
432
432
|
|
|
433
433
|
return instance
|
|
434
434
|
|
|
435
|
+
def _apply_default_values(self, kwargs: dict):
|
|
436
|
+
"""Apply default values for fields not provided in kwargs.
|
|
437
|
+
|
|
438
|
+
Args:
|
|
439
|
+
kwargs: Dictionary of provided field values (will be modified)
|
|
440
|
+
"""
|
|
441
|
+
for field_name in self._get_field_names():
|
|
442
|
+
if field_name not in kwargs or kwargs[field_name] is None:
|
|
443
|
+
default_value = self._get_field_default_value(field_name)
|
|
444
|
+
if default_value is not None:
|
|
445
|
+
kwargs[field_name] = default_value
|
|
446
|
+
|
|
447
|
+
def _get_field_default_value(self, field_name: str):
|
|
448
|
+
"""Get default value for a field.
|
|
449
|
+
|
|
450
|
+
Args:
|
|
451
|
+
field_name: Name of the field
|
|
452
|
+
|
|
453
|
+
Returns:
|
|
454
|
+
Default value or None if no default
|
|
455
|
+
"""
|
|
456
|
+
field_attr = getattr(self.__class__, field_name, None)
|
|
457
|
+
if field_attr is None:
|
|
458
|
+
return None
|
|
459
|
+
|
|
460
|
+
# Priority: default_factory > SQLAlchemy default
|
|
461
|
+
if hasattr(field_attr, "get_default_factory"):
|
|
462
|
+
factory = field_attr.get_default_factory()
|
|
463
|
+
if factory and callable(factory):
|
|
464
|
+
return factory()
|
|
465
|
+
|
|
466
|
+
if hasattr(field_attr, "default") and field_attr.default is not None:
|
|
467
|
+
default_value = field_attr.default
|
|
468
|
+
if callable(default_value):
|
|
469
|
+
return default_value()
|
|
470
|
+
else:
|
|
471
|
+
return default_value
|
|
472
|
+
|
|
473
|
+
return None
|
|
474
|
+
|
|
435
475
|
|
|
436
476
|
class FieldCacheMixin(DataConversionMixin):
|
|
437
477
|
"""Field caching and attribute access optimization - Layer 6."""
|
|
@@ -592,6 +632,13 @@ class FieldCacheMixin(DataConversionMixin):
|
|
|
592
632
|
|
|
593
633
|
relationship_fields = field_cache.get("relationship_fields", set())
|
|
594
634
|
if isinstance(relationship_fields, set) and name in relationship_fields:
|
|
635
|
+
# Check cascade_relationships first (manually assigned values)
|
|
636
|
+
if hasattr(self, "_state_manager"):
|
|
637
|
+
cascade_relationships: dict = self._state_manager.get("cascade_relationships", {}) # type: ignore[reportAssignmentType]
|
|
638
|
+
if name in cascade_relationships:
|
|
639
|
+
return cascade_relationships[name]
|
|
640
|
+
|
|
641
|
+
# Check preloaded cache
|
|
595
642
|
cache_name = f"_{name}_cache"
|
|
596
643
|
try:
|
|
597
644
|
if hasattr(self, cache_name):
|
|
@@ -601,6 +648,7 @@ class FieldCacheMixin(DataConversionMixin):
|
|
|
601
648
|
except AttributeError:
|
|
602
649
|
pass
|
|
603
650
|
|
|
651
|
+
# Only create proxy if relationship is not loaded
|
|
604
652
|
proxy_cache = self._state_manager.get("proxy_cache", {})
|
|
605
653
|
if isinstance(proxy_cache, dict) and name not in proxy_cache:
|
|
606
654
|
proxy_cache[name] = RelationFieldProxy(self, name)
|
|
@@ -110,8 +110,36 @@ class ModelMixin(FieldCacheMixin, SignalMixin):
|
|
|
110
110
|
if i < len(pk_values):
|
|
111
111
|
setattr(self, col.name, pk_values[i])
|
|
112
112
|
|
|
113
|
+
def _get_upsert_statement(self, table, data):
|
|
114
|
+
"""Construct UPSERT statement based on database dialect."""
|
|
115
|
+
dialect = self.get_session().bind.dialect.name
|
|
116
|
+
|
|
117
|
+
pk_columns = list(table.primary_key.columns)
|
|
118
|
+
|
|
119
|
+
if dialect == "postgresql":
|
|
120
|
+
from sqlalchemy.dialects.postgresql import insert
|
|
121
|
+
|
|
122
|
+
stmt = insert(table).values(**data)
|
|
123
|
+
return stmt.on_conflict_do_update(index_elements=pk_columns, set_=data)
|
|
124
|
+
|
|
125
|
+
elif dialect == "mysql":
|
|
126
|
+
from sqlalchemy.dialects.mysql import insert
|
|
127
|
+
|
|
128
|
+
stmt = insert(table).values(**data)
|
|
129
|
+
return stmt.on_duplicate_key_update(**data)
|
|
130
|
+
|
|
131
|
+
elif dialect == "sqlite":
|
|
132
|
+
from sqlalchemy.dialects.sqlite import insert
|
|
133
|
+
|
|
134
|
+
stmt = insert(table).values(**data)
|
|
135
|
+
return stmt.on_conflict_do_update(index_elements=pk_columns, set_=data)
|
|
136
|
+
|
|
137
|
+
else:
|
|
138
|
+
# Return None for unsupported dialects to trigger fallback
|
|
139
|
+
return None
|
|
140
|
+
|
|
113
141
|
async def _save_internal(self, validate: bool = True, session=None):
|
|
114
|
-
"""Internal save operation
|
|
142
|
+
"""Internal save operation using UPSERT with fallback to query-then-save.
|
|
115
143
|
|
|
116
144
|
This method contains the core save logic that can be reused by both
|
|
117
145
|
the public save() method and the cascade executor without triggering
|
|
@@ -135,17 +163,37 @@ class ModelMixin(FieldCacheMixin, SignalMixin):
|
|
|
135
163
|
if validate:
|
|
136
164
|
self.validate_all_fields()
|
|
137
165
|
|
|
166
|
+
data = self._get_all_data()
|
|
167
|
+
|
|
168
|
+
# Try UPSERT for supported databases
|
|
169
|
+
upsert_stmt = self._get_upsert_statement(table, data)
|
|
170
|
+
if upsert_stmt is not None:
|
|
171
|
+
try:
|
|
172
|
+
result = await session.execute(upsert_stmt)
|
|
173
|
+
if result.inserted_primary_key:
|
|
174
|
+
self._set_primary_key_values(result.inserted_primary_key)
|
|
175
|
+
# Clear dirty fields after successful save
|
|
176
|
+
dirty_fields = self._state_manager.get("dirty_fields", set())
|
|
177
|
+
if isinstance(dirty_fields, set):
|
|
178
|
+
dirty_fields.clear()
|
|
179
|
+
return self
|
|
180
|
+
except Exception as e:
|
|
181
|
+
raise PrimaryKeyError(f"Upsert operation failed: {e}") from e
|
|
182
|
+
|
|
183
|
+
# Fallback: query database to determine INSERT or UPDATE
|
|
138
184
|
try:
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
185
|
+
pk_conditions = self._build_pk_conditions()
|
|
186
|
+
existing = await session.execute(select(table).where(and_(*pk_conditions)))
|
|
187
|
+
|
|
188
|
+
if existing.first():
|
|
189
|
+
# Record exists, perform UPDATE
|
|
142
190
|
update_data = self._get_dirty_data()
|
|
143
191
|
if update_data:
|
|
144
192
|
stmt = update(table).where(and_(*pk_conditions)).values(**update_data)
|
|
145
193
|
await session.execute(stmt)
|
|
146
194
|
else:
|
|
147
|
-
# INSERT
|
|
148
|
-
stmt = insert(table).values(**
|
|
195
|
+
# Record does not exist, perform INSERT
|
|
196
|
+
stmt = insert(table).values(**data)
|
|
149
197
|
result = await session.execute(stmt)
|
|
150
198
|
if result.inserted_primary_key:
|
|
151
199
|
self._set_primary_key_values(result.inserted_primary_key)
|
|
@@ -219,8 +267,8 @@ class ModelMixin(FieldCacheMixin, SignalMixin):
|
|
|
219
267
|
for rel_name, new_related_objects in cascade_relationships.items():
|
|
220
268
|
await self._process_relationship_update(rel_name, new_related_objects, session)
|
|
221
269
|
|
|
222
|
-
#
|
|
223
|
-
self._state_manager.set("cascade_relationships", {})
|
|
270
|
+
# keep cascade_relationships
|
|
271
|
+
# self._state_manager.set("cascade_relationships", {})
|
|
224
272
|
self._state_manager.set("needs_cascade_save", False)
|
|
225
273
|
|
|
226
274
|
async def _process_relationship_update(self, rel_name: str, new_related_objects, session):
|
|
@@ -261,32 +309,30 @@ class ModelMixin(FieldCacheMixin, SignalMixin):
|
|
|
261
309
|
|
|
262
310
|
async def _fetch_current_related_objects(self, rel_name: str, session) -> list:
|
|
263
311
|
"""Fetch current related objects from database."""
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
"profile": ("CascadeProfile", "user_id"),
|
|
268
|
-
}
|
|
312
|
+
relationships = getattr(self.__class__, "_relationships", {})
|
|
313
|
+
if rel_name not in relationships:
|
|
314
|
+
return []
|
|
269
315
|
|
|
270
|
-
|
|
316
|
+
rel_descriptor = relationships[rel_name]
|
|
317
|
+
if not hasattr(rel_descriptor.property, "resolved_model") or not rel_descriptor.property.resolved_model:
|
|
271
318
|
return []
|
|
272
319
|
|
|
273
|
-
|
|
320
|
+
related_model = rel_descriptor.property.resolved_model
|
|
321
|
+
foreign_keys = rel_descriptor.property.foreign_keys
|
|
274
322
|
|
|
275
|
-
|
|
276
|
-
if related_model_name == "CascadePost":
|
|
277
|
-
from tests.integration.test_cascade_integration import CascadePost as RelatedModel
|
|
278
|
-
elif related_model_name == "CascadeProfile":
|
|
279
|
-
from tests.integration.test_cascade_integration import CascadeProfile as RelatedModel
|
|
280
|
-
else:
|
|
323
|
+
if not foreign_keys:
|
|
281
324
|
return []
|
|
282
325
|
|
|
283
|
-
#
|
|
326
|
+
# fetch foreign keys
|
|
327
|
+
fk_field = foreign_keys if isinstance(foreign_keys, str) else foreign_keys[0]
|
|
328
|
+
|
|
329
|
+
# get pk
|
|
284
330
|
pk_value = getattr(self, self._get_primary_key_field())
|
|
285
331
|
if pk_value is None:
|
|
286
332
|
return []
|
|
287
333
|
|
|
288
334
|
current_objects = (
|
|
289
|
-
await
|
|
335
|
+
await related_model.objects.using(session).filter(getattr(related_model, fk_field) == pk_value).all()
|
|
290
336
|
)
|
|
291
337
|
|
|
292
338
|
return current_objects
|
|
@@ -431,23 +477,18 @@ class ModelMixin(FieldCacheMixin, SignalMixin):
|
|
|
431
477
|
from .cascade import OnDelete
|
|
432
478
|
|
|
433
479
|
relationships = getattr(self.__class__, "_relationships", {})
|
|
434
|
-
|
|
435
|
-
for
|
|
436
|
-
print(f"DEBUG: Checking relationship {rel_name}")
|
|
480
|
+
|
|
481
|
+
for _, rel_descriptor in relationships.items():
|
|
437
482
|
if hasattr(rel_descriptor, "property") and hasattr(rel_descriptor.property, "cascade"):
|
|
438
483
|
cascade_str = rel_descriptor.property.cascade
|
|
439
|
-
print(f"DEBUG: Cascade string: {cascade_str}")
|
|
440
484
|
if cascade_str and ("delete" in cascade_str or "all" in cascade_str):
|
|
441
|
-
print(f"DEBUG: Found delete cascade relationship: {rel_name}")
|
|
442
485
|
return True
|
|
443
486
|
if (
|
|
444
487
|
hasattr(rel_descriptor, "property")
|
|
445
488
|
and hasattr(rel_descriptor.property, "on_delete")
|
|
446
489
|
and rel_descriptor.property.on_delete != OnDelete.NO_ACTION
|
|
447
490
|
):
|
|
448
|
-
print(f"DEBUG: Found on_delete relationship: {rel_name}")
|
|
449
491
|
return True
|
|
450
|
-
print("DEBUG: No on_delete relations found")
|
|
451
492
|
return False
|
|
452
493
|
|
|
453
494
|
def _get_primary_key_field(self) -> str:
|
|
@@ -503,46 +544,6 @@ class ModelMixin(FieldCacheMixin, SignalMixin):
|
|
|
503
544
|
relationships = getattr(self.__class__, "_relationships", {})
|
|
504
545
|
return set(relationships.keys())
|
|
505
546
|
|
|
506
|
-
def _apply_default_values(self, kwargs: dict):
|
|
507
|
-
"""Apply default values for fields not provided in kwargs.
|
|
508
|
-
|
|
509
|
-
Args:
|
|
510
|
-
kwargs: Dictionary of provided field values (will be modified)
|
|
511
|
-
"""
|
|
512
|
-
for field_name in self._get_field_names():
|
|
513
|
-
if field_name not in kwargs or kwargs[field_name] is None:
|
|
514
|
-
default_value = self._get_field_default_value(field_name)
|
|
515
|
-
if default_value is not None:
|
|
516
|
-
kwargs[field_name] = default_value
|
|
517
|
-
|
|
518
|
-
def _get_field_default_value(self, field_name: str):
|
|
519
|
-
"""Get default value for a field.
|
|
520
|
-
|
|
521
|
-
Args:
|
|
522
|
-
field_name: Name of the field
|
|
523
|
-
|
|
524
|
-
Returns:
|
|
525
|
-
Default value or None if no default
|
|
526
|
-
"""
|
|
527
|
-
field_attr = getattr(self.__class__, field_name, None)
|
|
528
|
-
if field_attr is None:
|
|
529
|
-
return None
|
|
530
|
-
|
|
531
|
-
# Priority: default_factory > SQLAlchemy default
|
|
532
|
-
if hasattr(field_attr, "get_default_factory"):
|
|
533
|
-
factory = field_attr.get_default_factory()
|
|
534
|
-
if factory and callable(factory):
|
|
535
|
-
return factory()
|
|
536
|
-
|
|
537
|
-
if hasattr(field_attr, "default") and field_attr.default is not None:
|
|
538
|
-
default_value = field_attr.default
|
|
539
|
-
if callable(default_value):
|
|
540
|
-
return default_value()
|
|
541
|
-
else:
|
|
542
|
-
return default_value
|
|
543
|
-
|
|
544
|
-
return None
|
|
545
|
-
|
|
546
547
|
|
|
547
548
|
class ObjectModel(ModelMixin, metaclass=ModelProcessor):
|
|
548
549
|
"""Base model class with configuration support and common functionality.
|
|
@@ -323,19 +323,16 @@ class BulkOperationHandler:
|
|
|
323
323
|
exec_session = session or self.session
|
|
324
324
|
|
|
325
325
|
if return_columns and self.supports_returning(operation):
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
return objects, result.rowcount or 0, True
|
|
337
|
-
except Exception: # noqa
|
|
338
|
-
pass # Fall through to regular execution
|
|
326
|
+
stmt_with_returning = stmt.returning(*return_columns)
|
|
327
|
+
# For INSERT operations, use the data directly as parameters
|
|
328
|
+
if operation == "insert" and isinstance(parameters, list):
|
|
329
|
+
result = await exec_session.execute(stmt_with_returning, parameters)
|
|
330
|
+
elif parameters:
|
|
331
|
+
result = await exec_session.execute(stmt_with_returning, parameters)
|
|
332
|
+
else:
|
|
333
|
+
result = await exec_session.execute(stmt_with_returning)
|
|
334
|
+
objects = self.create_objects_from_rows(result.fetchall(), return_fields)
|
|
335
|
+
return objects, result.rowcount or 0, True
|
|
339
336
|
|
|
340
337
|
# Regular execution without RETURNING
|
|
341
338
|
if parameters is not None and isinstance(parameters, list) and len(parameters) > 1:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sqlobjects
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.4
|
|
4
4
|
Summary: Django-style async ORM library based on SQLAlchemy with chainable queries, Q objects, and relationship loading
|
|
5
5
|
Author-email: XtraVisions <gitadmin@xtravisions.com>, Chen Hao <chenhao@xtravisions.com>
|
|
6
6
|
Maintainer-email: XtraVisions <gitadmin@xtravisions.com>, Chen Hao <chenhao@xtravisions.com>
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|