ormlambda 4.4.0__tar.gz → 4.4.14__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.
- {ormlambda-4.4.0 → ormlambda-4.4.14}/PKG-INFO +8 -4
- {ormlambda-4.4.0 → ormlambda-4.4.14}/README.md +2 -2
- {ormlambda-4.4.0 → ormlambda-4.4.14}/pyproject.toml +20 -4
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/__init__.py +12 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/common/__init__.py +1 -0
- ormlambda-4.4.14/src/ormlambda/common/constants.py +1 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/common/enums/union_type.py +1 -1
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/common/errors/__init__.py +53 -1
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/common/global_checker.py +1 -1
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/mysql/base.py +58 -42
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/mysql/caster/caster.py +3 -1
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/mysql/caster/types/__init__.py +1 -1
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/mysql/caster/types/json.py +1 -0
- ormlambda-4.4.14/src/ormlambda/dialects/mysql/repository/__init__.py +1 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/mysql/repository/repository.py +0 -2
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/repository/response.py +13 -3
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/clause_info/clause_info.py +108 -71
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/clauses/alias.py +1 -1
- ormlambda-4.4.14/src/ormlambda/sql/clauses/delete.py +25 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/clauses/insert.py +1 -1
- ormlambda-4.4.14/src/ormlambda/sql/clauses/update.py +26 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/clauses/where.py +0 -1
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/column/column.py +42 -49
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/column/column_proxy.py +4 -0
- {ormlambda-4.4.0/src/ormlambda/types → ormlambda-4.4.14/src/ormlambda/sql/column}/metadata.py +10 -7
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/compiler.py +6 -1
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/ddl.py +2 -2
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/functions/interface/__init__.py +1 -3
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/sqltypes.py +20 -2
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/table/fields.py +4 -6
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/table/table.py +34 -1
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/type_api.py +8 -4
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/statements/interfaces/IStatements.py +28 -8
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/statements/query_builder.py +25 -21
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/statements/statements.py +19 -22
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/statements/types.py +1 -1
- ormlambda-4.4.14/src/ormlambda/util/__init__.py +50 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/util/langhelpers.py +1 -1
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/util/preloaded.py +2 -1
- ormlambda-4.4.0/src/ormlambda/dialects/mysql/repository/__init__.py +0 -1
- ormlambda-4.4.0/src/ormlambda/errors.py +0 -26
- ormlambda-4.4.0/src/ormlambda/sql/clauses/delete.py +0 -21
- ormlambda-4.4.0/src/ormlambda/sql/clauses/update.py +0 -23
- ormlambda-4.4.0/src/ormlambda/types/__init__.py +0 -24
- ormlambda-4.4.0/src/ormlambda/util/__init__.py +0 -9
- {ormlambda-4.4.0 → ormlambda-4.4.14}/AUTHORS +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/LICENSE +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/caster/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/caster/base_caster.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/caster/caster.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/caster/interfaces/ICaster.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/caster/interfaces/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/common/enums/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/common/enums/condition_types.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/common/enums/join_type.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/common/enums/order_type.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/common/interfaces/IJoinSelector.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/common/interfaces/IQueryCommand.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/common/interfaces/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/default/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/default/base.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/mysql/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/mysql/caster/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/mysql/caster/types/boolean.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/mysql/caster/types/bytes.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/mysql/caster/types/date.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/mysql/caster/types/datetime.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/mysql/caster/types/decimal.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/mysql/caster/types/float.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/mysql/caster/types/int.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/mysql/caster/types/iterable.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/mysql/caster/types/none.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/mysql/caster/types/point.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/mysql/caster/types/string.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/mysql/clauses/ST_AsText.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/mysql/clauses/ST_Contains.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/mysql/clauses/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/mysql/mysqlconnector.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/mysql/repository/pool_types.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/mysql/types.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/sqlite/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/sqlite/base.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/dialects/sqlite/pysqlite.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/engine/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/engine/base.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/engine/create.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/engine/url.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/engine/utils.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/env.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/model/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/model/base_model.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/repository/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/repository/base_repository.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/repository/interfaces/IDatabaseConnection.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/repository/interfaces/IRepositoryBase.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/repository/interfaces/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/clause_info/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/clause_info/interface/IClauseInfo.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/clause_info/interface/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/clauses/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/clauses/group_by.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/clauses/having.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/clauses/join/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/clauses/join/join_context.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/clauses/joins.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/clauses/limit.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/clauses/offset.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/clauses/order.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/clauses/select.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/clauses/upsert.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/column/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/column_table_proxy.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/comparer.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/context/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/elements.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/foreign_key.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/functions/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/functions/aggregate/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/functions/aggregate/avg.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/functions/aggregate/concat.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/functions/aggregate/count.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/functions/aggregate/max.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/functions/aggregate/min.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/functions/aggregate/sum.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/functions/base.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/functions/datetime/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/functions/mathematical/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/functions/mathematical/abs.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/functions/mathematical/ceil.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/functions/mathematical/floor.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/functions/mathematical/mod.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/functions/mathematical/pow.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/functions/mathematical/rand.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/functions/mathematical/round.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/functions/mathematical/sqrt.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/functions/mathematical/truncate.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/functions/string/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/table/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/table/table_constructor.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/table/table_proxy.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/types.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/sql/visitors.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/statements/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/statements/base_statement.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/statements/interfaces/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/util/module_tree/__init__.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/util/module_tree/dfs_traversal.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/util/module_tree/dynamic_module.py +0 -0
- {ormlambda-4.4.0 → ormlambda-4.4.14}/src/ormlambda/util/typing.py +0 -0
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: ormlambda
|
|
3
|
-
Version: 4.4.
|
|
3
|
+
Version: 4.4.14
|
|
4
4
|
Summary: ORM designed to interact with the database (currently with MySQL) using lambda functions and nested functions
|
|
5
|
+
License-File: AUTHORS
|
|
6
|
+
License-File: LICENSE
|
|
5
7
|
Author: p-hzamora
|
|
6
8
|
Author-email: p.hzamora@icloud.com
|
|
7
9
|
Requires-Python: >=3.12,<4.0
|
|
8
10
|
Classifier: Programming Language :: Python :: 3
|
|
9
11
|
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
10
14
|
Requires-Dist: mysql-connector-python (>=9.0.0,<10.0.0)
|
|
11
15
|
Requires-Dist: shapely (>=2.0.6,<3.0.0)
|
|
12
16
|
Description-Content-Type: text/markdown
|
|
@@ -76,7 +80,7 @@ db = create_engine('mysql://root:1234@localhost:3306/sakila')
|
|
|
76
80
|
|
|
77
81
|
AddressModel = ORM(Address, db)
|
|
78
82
|
|
|
79
|
-
result = AddressModel.where(
|
|
83
|
+
result = AddressModel.where(lambda x: x.City.Country.country.regex(r"^[aA]")).select(
|
|
80
84
|
lambda address: (
|
|
81
85
|
address,
|
|
82
86
|
address.City,
|
|
@@ -104,7 +108,7 @@ result = AddressModel.where(
|
|
|
104
108
|
Additionally, we can filter by others tables. For example, we can return all addresses for each city where `country_id` = 87 (Spain)
|
|
105
109
|
|
|
106
110
|
```python
|
|
107
|
-
result = AddressModel.where(
|
|
111
|
+
result = AddressModel.where(lambda x: x.City.Country.country_id == 87).select()
|
|
108
112
|
```
|
|
109
113
|
|
|
110
114
|
We can also return `Address`, `City` or `Country` if needed.
|
|
@@ -63,7 +63,7 @@ db = create_engine('mysql://root:1234@localhost:3306/sakila')
|
|
|
63
63
|
|
|
64
64
|
AddressModel = ORM(Address, db)
|
|
65
65
|
|
|
66
|
-
result = AddressModel.where(
|
|
66
|
+
result = AddressModel.where(lambda x: x.City.Country.country.regex(r"^[aA]")).select(
|
|
67
67
|
lambda address: (
|
|
68
68
|
address,
|
|
69
69
|
address.City,
|
|
@@ -91,7 +91,7 @@ result = AddressModel.where(
|
|
|
91
91
|
Additionally, we can filter by others tables. For example, we can return all addresses for each city where `country_id` = 87 (Spain)
|
|
92
92
|
|
|
93
93
|
```python
|
|
94
|
-
result = AddressModel.where(
|
|
94
|
+
result = AddressModel.where(lambda x: x.City.Country.country_id == 87).select()
|
|
95
95
|
```
|
|
96
96
|
|
|
97
97
|
We can also return `Address`, `City` or `Country` if needed.
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
[tool.ruff]
|
|
2
|
-
line-length = 320
|
|
3
|
-
|
|
4
1
|
[tool.poetry]
|
|
5
2
|
name = "ormlambda"
|
|
6
|
-
version = "4.4.
|
|
3
|
+
version = "4.4.14"
|
|
7
4
|
description = "ORM designed to interact with the database (currently with MySQL) using lambda functions and nested functions"
|
|
8
5
|
authors = ["p-hzamora <p.hzamora@icloud.com>"]
|
|
9
6
|
readme = "README.md"
|
|
@@ -21,8 +18,27 @@ ruff = "^0.4.5"
|
|
|
21
18
|
parameterized = "^0.9.0"
|
|
22
19
|
pydantic = "^2.11.1"
|
|
23
20
|
sqlserver = "^0.0.17.1"
|
|
21
|
+
pytest = "^8.4.2"
|
|
22
|
+
|
|
23
|
+
[tool.ruff]
|
|
24
|
+
line-length = 320
|
|
24
25
|
|
|
26
|
+
[tool.pytest.ini_options]
|
|
27
|
+
testpaths = ["src/test"]
|
|
28
|
+
python_files = ["test_*.py"]
|
|
29
|
+
python_classes = ["Test*"]
|
|
30
|
+
python_functions = ["test_*"]
|
|
31
|
+
addopts = [
|
|
32
|
+
"-v", # verbose output
|
|
33
|
+
"--strict-markers", # error on unknown markers
|
|
34
|
+
"--tb=short", # shorter traceback format
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
markers = [
|
|
38
|
+
"slow: Slow test (deselect with '-m \"not slow\"')",
|
|
39
|
+
]
|
|
25
40
|
|
|
26
41
|
[build-system]
|
|
27
42
|
requires = ["poetry-core"]
|
|
28
43
|
build-backend = "poetry.core.masonry.api"
|
|
44
|
+
|
|
@@ -80,4 +80,16 @@ from .sql import functions as functions
|
|
|
80
80
|
from .sql.functions import * # noqa: F403
|
|
81
81
|
from . import util as _util
|
|
82
82
|
|
|
83
|
+
|
|
84
|
+
from .sql.column.metadata import PrimaryKey as PrimaryKey
|
|
85
|
+
from .sql.column.metadata import AutoGenerated as AutoGenerated
|
|
86
|
+
from .sql.column.metadata import AutoIncrement as AutoIncrement
|
|
87
|
+
from .sql.column.metadata import Unique as Unique
|
|
88
|
+
from .sql.column.metadata import CheckTypes as CheckTypes
|
|
89
|
+
from .sql.column.metadata import Default as Default
|
|
90
|
+
from .sql.column.metadata import NotNull as NotNull
|
|
91
|
+
|
|
92
|
+
from ormlambda.statements.interfaces import IStatements as IStatements
|
|
93
|
+
from ormlambda.engine import Engine as Engine
|
|
94
|
+
|
|
83
95
|
_util.import_prefix("ormlambda")
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
DOT = "."
|
|
@@ -6,6 +6,17 @@ from ormlambda import util
|
|
|
6
6
|
|
|
7
7
|
if tp.TYPE_CHECKING:
|
|
8
8
|
from ormlambda.sql.clause_info import ClauseInfo
|
|
9
|
+
from ormlambda.sql import Column
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ReplacePlaceholderError(ValueError):
|
|
13
|
+
def __init__(self, placeholder: str, attribute: str, *args):
|
|
14
|
+
super().__init__(*args)
|
|
15
|
+
self.placeholder: str = placeholder
|
|
16
|
+
self.attr: str = attribute
|
|
17
|
+
|
|
18
|
+
def __str__(self):
|
|
19
|
+
return "You cannot use {" + self.placeholder + "} placeholder without using '" + self.attr + "' attribute"
|
|
9
20
|
|
|
10
21
|
|
|
11
22
|
class UnmatchedLambdaParameterError(Exception):
|
|
@@ -42,7 +53,7 @@ class FunctionFunctionError[T](Exception):
|
|
|
42
53
|
Get the class name of those classes that inherit from 'IFunction' class in order to create a better error message.
|
|
43
54
|
"""
|
|
44
55
|
|
|
45
|
-
IFunction = util.preloaded.sql_functions.IFunction
|
|
56
|
+
IFunction = util.preloaded.sql_functions.IFunction
|
|
46
57
|
res: set[str] = set()
|
|
47
58
|
if not isinstance(clauses, tp.Iterable):
|
|
48
59
|
return clauses.__class__.__name__
|
|
@@ -58,3 +69,44 @@ class NotCallableError(ValueError):
|
|
|
58
69
|
|
|
59
70
|
def __str__(self) -> str:
|
|
60
71
|
return f"You must provide a function or callable to proceed with the query creation. Passed '{self.args[0].__class__.__name__}' "
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class CompileError(Exception):
|
|
75
|
+
"""Exception raised for errors in the compilation process."""
|
|
76
|
+
|
|
77
|
+
def __init__(self, message):
|
|
78
|
+
super().__init__(message)
|
|
79
|
+
self.message = message
|
|
80
|
+
|
|
81
|
+
def __str__(self):
|
|
82
|
+
return f"CompileError: {self.message}"
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class NoSuchModuleError(Exception):
|
|
86
|
+
"""Raised when a dynamically-loaded module (usually a database dialect)
|
|
87
|
+
of a particular name cannot be located."""
|
|
88
|
+
|
|
89
|
+
def __str__(self):
|
|
90
|
+
return f"NoSuchModuleError: {self.args[0]}"
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class DuplicatedClauseNameError(Exception):
|
|
94
|
+
def __init__(self, names: tuple[str], **kw):
|
|
95
|
+
self.names = names
|
|
96
|
+
super().__init__(**kw)
|
|
97
|
+
|
|
98
|
+
def __str__(self):
|
|
99
|
+
return f"Some clauses has the same alias. {self.names}\nTry wrapping the clause with the 'Alias' class first or setting 'avoid_duplicates' param as 'True'"
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class ColumnError(ValueError):
|
|
103
|
+
def __init__(self, column: Column, *args):
|
|
104
|
+
super().__init__(*args)
|
|
105
|
+
self.column = column
|
|
106
|
+
self.clause: str = ""
|
|
107
|
+
|
|
108
|
+
def set_clause(self, value: str) -> None:
|
|
109
|
+
self.clause = value
|
|
110
|
+
|
|
111
|
+
def __str__(self):
|
|
112
|
+
return f"The column '{self.column.column_name}' does not exist. Check the name you used inside of '{self.clause}' clause."
|
|
@@ -11,15 +11,6 @@ from .. import default
|
|
|
11
11
|
from typing import TYPE_CHECKING, Any, Iterable, Type
|
|
12
12
|
from ormlambda.sql.comparer import Comparer, ComparerCluster
|
|
13
13
|
|
|
14
|
-
if TYPE_CHECKING:
|
|
15
|
-
from ormlambda.sql.functions.interface import IFunction
|
|
16
|
-
from ormlambda.sql.types import ColumnType
|
|
17
|
-
from test.test_clause_info import ST_Contains
|
|
18
|
-
from ormlambda import JoinSelector
|
|
19
|
-
from ormlambda.sql.column.column import Column
|
|
20
|
-
from mysql import connector
|
|
21
|
-
from ormlambda.dialects.mysql.clauses import ST_AsText
|
|
22
|
-
|
|
23
14
|
from .types import (
|
|
24
15
|
_NumericType,
|
|
25
16
|
_NumericCommonType,
|
|
@@ -64,6 +55,14 @@ from .repository import MySQLRepository
|
|
|
64
55
|
|
|
65
56
|
|
|
66
57
|
if TYPE_CHECKING:
|
|
58
|
+
from ormlambda.sql.functions.interface import IFunction
|
|
59
|
+
from ormlambda.sql.types import ColumnType
|
|
60
|
+
from test.test_clause_info import ST_Contains
|
|
61
|
+
from ormlambda import JoinSelector
|
|
62
|
+
from ormlambda.sql.column.column import Column
|
|
63
|
+
from mysql import connector
|
|
64
|
+
from ormlambda.dialects.mysql.clauses import ST_AsText
|
|
65
|
+
|
|
67
66
|
from ormlambda.sql.clauses import (
|
|
68
67
|
Select,
|
|
69
68
|
Insert,
|
|
@@ -103,10 +102,10 @@ class MySQLCompiler(compiler.SQLCompiler):
|
|
|
103
102
|
|
|
104
103
|
def visit_table_proxy(self, table: TableProxy, **kw) -> str:
|
|
105
104
|
param = {
|
|
106
|
-
"table":
|
|
107
|
-
"column":
|
|
108
|
-
"dialect": self.dialect,
|
|
105
|
+
"table": table._table_class,
|
|
106
|
+
"column": None,
|
|
109
107
|
"alias_clause": alias if (alias := table.get_table_chain()) else None,
|
|
108
|
+
"dialect": self.dialect,
|
|
110
109
|
**kw,
|
|
111
110
|
}
|
|
112
111
|
return ClauseInfo(**param).query(dialect=self.dialect)
|
|
@@ -129,7 +128,7 @@ class MySQLCompiler(compiler.SQLCompiler):
|
|
|
129
128
|
params = {
|
|
130
129
|
"table": column.table,
|
|
131
130
|
"column": column,
|
|
132
|
-
"alias_table": alias_table
|
|
131
|
+
"alias_table": alias_table,
|
|
133
132
|
"alias_clause": column.alias or "{column}",
|
|
134
133
|
"dtype": column._column.dtype,
|
|
135
134
|
"dialect": self.dialect,
|
|
@@ -167,7 +166,7 @@ class MySQLCompiler(compiler.SQLCompiler):
|
|
|
167
166
|
|
|
168
167
|
return f"{lcond} {comparer.compare} {rcond}"
|
|
169
168
|
|
|
170
|
-
def visit_where(self, where: Where) -> str:
|
|
169
|
+
def visit_where(self, where: Where, sep: str = " ", **kw) -> str:
|
|
171
170
|
assert (n := len(where.comparers)) == len(where.restrictive)
|
|
172
171
|
|
|
173
172
|
if not where.comparers:
|
|
@@ -178,17 +177,17 @@ class MySQLCompiler(compiler.SQLCompiler):
|
|
|
178
177
|
for i in range(n):
|
|
179
178
|
comp = where.comparers[i]
|
|
180
179
|
|
|
181
|
-
string = comp.compile(self.dialect).string
|
|
180
|
+
string = comp.compile(self.dialect, **kw).string
|
|
182
181
|
|
|
183
182
|
condition = f"({string})" if isinstance(comp, ComparerCluster) else string
|
|
184
183
|
|
|
185
|
-
union = f" {where.restrictive[i + 1]}
|
|
184
|
+
union = f" {where.restrictive[i + 1]}{sep}" if i != n - 1 else ""
|
|
186
185
|
|
|
187
186
|
condition += union
|
|
188
187
|
cond.append(condition)
|
|
189
|
-
return f"
|
|
188
|
+
return f"WHERE{sep}{''.join(cond)}"
|
|
190
189
|
|
|
191
|
-
def visit_having(self, having: Having) -> str:
|
|
190
|
+
def visit_having(self, having: Having, sep: str = " ", **kw) -> str:
|
|
192
191
|
assert (n := len(having.comparers)) == len(having.restrictive)
|
|
193
192
|
|
|
194
193
|
if not having.comparers:
|
|
@@ -199,23 +198,23 @@ class MySQLCompiler(compiler.SQLCompiler):
|
|
|
199
198
|
for i in range(n):
|
|
200
199
|
comp = having.comparers[i]
|
|
201
200
|
|
|
202
|
-
string = comp.compile(self.dialect).string
|
|
201
|
+
string = comp.compile(self.dialect, **kw).string
|
|
203
202
|
|
|
204
203
|
condition = f"({string})" if isinstance(comp, ComparerCluster) else string
|
|
205
204
|
|
|
206
|
-
union = f" {having.restrictive[i + 1]}
|
|
205
|
+
union = f" {having.restrictive[i + 1]}{sep}" if i != n - 1 else ""
|
|
207
206
|
|
|
208
207
|
condition += union
|
|
209
208
|
cond.append(condition)
|
|
210
|
-
return f"
|
|
209
|
+
return f"HAVING{sep}{''.join(cond)}"
|
|
211
210
|
|
|
212
211
|
def visit_join(self, join: JoinSelector) -> str:
|
|
213
212
|
rt = join.rcon.table
|
|
214
213
|
rtable = TableProxy(table_class=rt, path=join.rcon.path)
|
|
215
214
|
|
|
216
|
-
from_clause = rtable.compile(self.dialect,
|
|
215
|
+
from_clause = rtable.compile(self.dialect, alias_table=join.alias, first_apperance=True).string
|
|
217
216
|
left_table_clause = join.lcon.compile(self.dialect, alias_clause=None).string
|
|
218
|
-
right_table_clause = join.rcon.compile(self.dialect,
|
|
217
|
+
right_table_clause = join.rcon.compile(self.dialect, alias_clause=None).string
|
|
219
218
|
list_ = [
|
|
220
219
|
join._by.value, # inner join
|
|
221
220
|
from_clause,
|
|
@@ -226,7 +225,7 @@ class MySQLCompiler(compiler.SQLCompiler):
|
|
|
226
225
|
]
|
|
227
226
|
return " ".join([x for x in list_ if x is not None])
|
|
228
227
|
|
|
229
|
-
def visit_select(self, select: Select):
|
|
228
|
+
def visit_select(self, select: Select, sep: str = " ", **kw):
|
|
230
229
|
params = {}
|
|
231
230
|
|
|
232
231
|
# COMMENT: when passing alias into 'select' method, we gonna replace the current aliases of columns with the generic one.
|
|
@@ -236,15 +235,17 @@ class MySQLCompiler(compiler.SQLCompiler):
|
|
|
236
235
|
elif select.alias:
|
|
237
236
|
params["alias_clause"] = select.alias
|
|
238
237
|
|
|
239
|
-
columns = ClauseInfo.join_clauses(select.columns,
|
|
238
|
+
columns = ClauseInfo.join_clauses(select.columns, sep, dialect=self.dialect, **params)
|
|
239
|
+
|
|
240
240
|
from_ = ClauseInfo(
|
|
241
|
-
select._table,
|
|
242
|
-
None,
|
|
243
|
-
alias_table=
|
|
241
|
+
table=select._table,
|
|
242
|
+
column=None,
|
|
243
|
+
alias_table="{table}",
|
|
244
244
|
dialect=self.dialect,
|
|
245
|
+
first_apperance=True,
|
|
245
246
|
).query(self.dialect)
|
|
246
247
|
|
|
247
|
-
return f"SELECT
|
|
248
|
+
return f"SELECT{sep}{columns}{sep}FROM {from_}"
|
|
248
249
|
|
|
249
250
|
def visit_group_by(self, groupby: GroupBy):
|
|
250
251
|
column = ", ".join(x.compile(self.dialect, alias_clause=None).string for x in groupby.column)
|
|
@@ -320,11 +321,18 @@ class MySQLCompiler(compiler.SQLCompiler):
|
|
|
320
321
|
unknown_rows = f"({', '.join(wildcards)})" # The number of "%s" must match the dict 'dicc_0' length
|
|
321
322
|
|
|
322
323
|
insert.cleaned_values = [tuple(x) for x in col_values]
|
|
323
|
-
query = f"INSERT INTO {insert.table
|
|
324
|
+
query = f"INSERT INTO {self.visit_table(insert.table)} {f'({join_cols})'} VALUES {unknown_rows}"
|
|
324
325
|
return query
|
|
325
326
|
|
|
326
327
|
def visit_delete(self, delete: Delete, **kw) -> str:
|
|
327
|
-
|
|
328
|
+
query = f"DELETE FROM {self.visit_table(delete.table)}"
|
|
329
|
+
|
|
330
|
+
if delete.where.comparers:
|
|
331
|
+
# COMMENT: We need to change the Where.restrictive due to if we use more than one where, we want to use "OR" instead "AND"
|
|
332
|
+
for x in range(len(delete.where.restrictive)):
|
|
333
|
+
delete.where.restrictive[x] = "OR"
|
|
334
|
+
query += " " + delete.where.compile(self.dialect).string
|
|
335
|
+
return query
|
|
328
336
|
|
|
329
337
|
def visit_upsert(self, upsert: Upsert, **kw) -> str:
|
|
330
338
|
"""
|
|
@@ -436,6 +444,11 @@ class MySQLCompiler(compiler.SQLCompiler):
|
|
|
436
444
|
set_query: str = ",".join(["=".join(col_data) for col_data in col_names])
|
|
437
445
|
|
|
438
446
|
query = f"UPDATE {update.table.__table_name__} SET {set_query}"
|
|
447
|
+
|
|
448
|
+
if update.where.comparers:
|
|
449
|
+
where_string = update.where.compile(self.dialect).string
|
|
450
|
+
|
|
451
|
+
query += " " + where_string
|
|
439
452
|
update.cleaned_values = tuple(update.cleaned_values)
|
|
440
453
|
return query
|
|
441
454
|
|
|
@@ -452,7 +465,7 @@ class MySQLCompiler(compiler.SQLCompiler):
|
|
|
452
465
|
else:
|
|
453
466
|
column = count.column
|
|
454
467
|
|
|
455
|
-
return ClauseInfo.
|
|
468
|
+
return ClauseInfo.concat_clause_with_his_alias(f"COUNT({column})", count.alias)
|
|
456
469
|
|
|
457
470
|
def visit_order(self, order: Order, **kw) -> str:
|
|
458
471
|
ORDER = "ORDER BY"
|
|
@@ -499,10 +512,10 @@ class MySQLCompiler(compiler.SQLCompiler):
|
|
|
499
512
|
clause_info = ClauseInfo(
|
|
500
513
|
table=None,
|
|
501
514
|
column=f"CONCAT({', '.join(columns)})",
|
|
502
|
-
alias_clause=concat.alias,
|
|
503
515
|
dialect=self.dialect,
|
|
516
|
+
literal=True
|
|
504
517
|
)
|
|
505
|
-
return clause_info.query(self.dialect)
|
|
518
|
+
return f"{clause_info.query(self.dialect)} AS {ClauseInfo.wrapped_with_quotes(concat.alias)}"
|
|
506
519
|
|
|
507
520
|
def visit_max(self, obj: Max, **kw) -> str:
|
|
508
521
|
return self._compile_aggregate_method("MAX", obj, **kw)
|
|
@@ -531,7 +544,7 @@ class MySQLCompiler(compiler.SQLCompiler):
|
|
|
531
544
|
def visit_pow(self, obj: Pow, **kw) -> str:
|
|
532
545
|
attr = {**kw, "alias_clause": None}
|
|
533
546
|
column = obj.column.compile(self.dialect, **attr).string
|
|
534
|
-
return ClauseInfo.
|
|
547
|
+
return ClauseInfo.concat_clause_with_his_alias(f"POW({column}, {obj._exponent})", obj.alias)
|
|
535
548
|
|
|
536
549
|
def visit_sqrt(self, obj: Sqrt, **kw) -> str:
|
|
537
550
|
return self._compile_aggregate_method("SQRT", obj, **kw)
|
|
@@ -539,7 +552,7 @@ class MySQLCompiler(compiler.SQLCompiler):
|
|
|
539
552
|
def visit_mod(self, obj: Mod, **kw) -> str:
|
|
540
553
|
attr = {**kw, "alias_clause": None}
|
|
541
554
|
column = obj.column.compile(self.dialect, **attr).string
|
|
542
|
-
return ClauseInfo.
|
|
555
|
+
return ClauseInfo.concat_clause_with_his_alias(f"MOD({column}, {obj._divisor})", obj.alias)
|
|
543
556
|
|
|
544
557
|
def visit_rand(self, obj: Rand, **kw) -> str:
|
|
545
558
|
return self._compile_aggregate_method("RAND", obj, **kw)
|
|
@@ -547,28 +560,30 @@ class MySQLCompiler(compiler.SQLCompiler):
|
|
|
547
560
|
def visit_truncate(self, obj: Truncate, **kw) -> str:
|
|
548
561
|
attr = {**kw, "alias_clause": None}
|
|
549
562
|
column = obj.column.compile(self.dialect, **attr).string
|
|
550
|
-
return ClauseInfo.
|
|
563
|
+
return ClauseInfo.concat_clause_with_his_alias(f"TRUNCATE({column}, {obj._decimal})", obj.alias)
|
|
551
564
|
|
|
552
565
|
def _compile_aggregate_method(self, name: str, function: IFunction, **kw) -> str:
|
|
553
566
|
attr = {**kw, "alias_clause": None}
|
|
554
567
|
column = function.column.compile(self.dialect, **attr).string
|
|
555
|
-
return ClauseInfo.
|
|
568
|
+
return ClauseInfo.concat_clause_with_his_alias(f"{name}({column})", function.alias)
|
|
556
569
|
|
|
557
570
|
def visit_st_astext(self, st_astext: ST_AsText) -> str:
|
|
558
571
|
# avoid use placeholder when using IFunction because no make sense.
|
|
559
572
|
if st_astext.alias and (found := ClauseInfo._keyRegex.findall(st_astext.alias)):
|
|
560
573
|
raise NotKeysInIFunctionError(found)
|
|
561
|
-
return ClauseInfo.
|
|
574
|
+
return ClauseInfo.concat_clause_with_his_alias(f"ST_AsText({st_astext.column.compile(self.dialect, alias_clause=None).string})", st_astext.alias)
|
|
562
575
|
|
|
563
576
|
def visit_st_contains(self, st_contains: ST_Contains) -> str:
|
|
577
|
+
# FIXME [ ]: It's not working as expected. Should be something like
|
|
578
|
+
# ST_Contains(`table_type`.points, ST_GeomFromText(%s))
|
|
564
579
|
attr1 = st_contains.column.compile(self.dialect, alias_clause=None).string
|
|
565
|
-
attr2 = ClauseInfo(None, st_contains.point, dialect=self.dialect).query(self.dialect
|
|
580
|
+
attr2 = ClauseInfo(None, st_contains.point, dialect=self.dialect).query(self.dialect)
|
|
566
581
|
return f"ST_Contains({attr1}, {attr2})"
|
|
567
582
|
|
|
568
583
|
|
|
569
584
|
class MySQLDDLCompiler(compiler.DDLCompiler):
|
|
570
585
|
def get_column_specification(self, column: Column, **kwargs):
|
|
571
|
-
colspec = column.column_name + " " + self.dialect.type_compiler_instance.process(column.
|
|
586
|
+
colspec = column.column_name + " " + self.dialect.type_compiler_instance.process(column.dtype)
|
|
572
587
|
default = self.get_column_default_string(column)
|
|
573
588
|
if default is not None:
|
|
574
589
|
colspec += " DEFAULT " + default
|
|
@@ -587,7 +602,8 @@ class MySQLDDLCompiler(compiler.DDLCompiler):
|
|
|
587
602
|
compare = fk.resolved_function()
|
|
588
603
|
lcon = compare.left_condition
|
|
589
604
|
rcon = compare.right_condition
|
|
590
|
-
|
|
605
|
+
rdb = f"{ClauseInfo.wrapped_with_quotes(db)}." if (db := compare.right_condition.table.__db_name__) else ""
|
|
606
|
+
return f"FOREIGN KEY ({lcon.column_name}) REFERENCES {rdb}{rcon.table.__table_name__}({rcon.column_name})"
|
|
591
607
|
|
|
592
608
|
|
|
593
609
|
class MySQLTypeCompiler(compiler.GenericTypeCompiler):
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
+
from typing import Union
|
|
2
3
|
from ormlambda.caster.caster import Caster
|
|
3
4
|
|
|
4
5
|
|
|
@@ -41,5 +42,6 @@ class MySQLCaster(Caster):
|
|
|
41
42
|
list: IterableCaster,
|
|
42
43
|
bool: BooleanCaster,
|
|
43
44
|
Decimal: DecimalCaster,
|
|
44
|
-
dict:JsonCaster
|
|
45
|
+
dict: JsonCaster,
|
|
46
|
+
Union[list | dict]: JsonCaster,
|
|
45
47
|
}
|
|
@@ -9,4 +9,4 @@ from .iterable import IterableCaster as IterableCaster
|
|
|
9
9
|
from .boolean import BooleanCaster as BooleanCaster
|
|
10
10
|
from .date import DateCaster as DateCaster
|
|
11
11
|
from .decimal import DecimalCaster as DecimalCaster
|
|
12
|
-
from .json import JsonCaster as JsonCaster
|
|
12
|
+
from .json import JsonCaster as JsonCaster
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .repository import MySQLRepository # noqa: F401
|
|
@@ -187,8 +187,6 @@ class MySQLRepository(BaseRepository[MySQLConnectionPool]):
|
|
|
187
187
|
@override
|
|
188
188
|
def table_exists(self, name: str) -> bool:
|
|
189
189
|
with self.get_connection() as cnx:
|
|
190
|
-
if not cnx.database:
|
|
191
|
-
raise Exception("No database selected")
|
|
192
190
|
with cnx.cursor(buffered=True) as cursor:
|
|
193
191
|
cursor.execute(f"SHOW TABLES LIKE {Caster.PLACEHOLDER};", (name,))
|
|
194
192
|
res = cursor.fetchmany(1)
|
|
@@ -5,8 +5,10 @@ import shapely as shp
|
|
|
5
5
|
|
|
6
6
|
# Custom libraries
|
|
7
7
|
from ormlambda.sql.clauses import Alias
|
|
8
|
+
from ormlambda import ColumnProxy
|
|
8
9
|
|
|
9
10
|
if TYPE_CHECKING:
|
|
11
|
+
from ormlambda.sql.types import SelectCol
|
|
10
12
|
from ormlambda.sql.clause_info import ClauseInfo
|
|
11
13
|
from ormlambda import Table
|
|
12
14
|
from ormlambda.sql.clauses import Select
|
|
@@ -69,12 +71,11 @@ class Response[TFlavour, *Ts]:
|
|
|
69
71
|
nonlocal data
|
|
70
72
|
result = []
|
|
71
73
|
for value in data:
|
|
72
|
-
if len(value) ==1:
|
|
74
|
+
if len(value) == 1:
|
|
73
75
|
result.append(value[0])
|
|
74
76
|
continue
|
|
75
77
|
result.append(value)
|
|
76
78
|
|
|
77
|
-
|
|
78
79
|
return result
|
|
79
80
|
|
|
80
81
|
def _set(**kwargs) -> list[set]:
|
|
@@ -130,7 +131,7 @@ class Response[TFlavour, *Ts]:
|
|
|
130
131
|
for i, data in enumerate(row):
|
|
131
132
|
alias = self._columns[i]
|
|
132
133
|
clause = self._select[alias]
|
|
133
|
-
dtype =
|
|
134
|
+
dtype = self.get_python_type(clause)
|
|
134
135
|
parse_data = self._caster.for_value(data, value_type=dtype).from_database
|
|
135
136
|
new_row.append(parse_data)
|
|
136
137
|
new_row = tuple(new_row)
|
|
@@ -146,3 +147,12 @@ class Response[TFlavour, *Ts]:
|
|
|
146
147
|
return False
|
|
147
148
|
|
|
148
149
|
return clause_info.dtype is shp.Point
|
|
150
|
+
|
|
151
|
+
@staticmethod
|
|
152
|
+
def get_python_type[T](value: SelectCol) -> Type[T]:
|
|
153
|
+
if isinstance(value, ColumnProxy):
|
|
154
|
+
return value.dtype.python_type
|
|
155
|
+
|
|
156
|
+
if hasattr(value, "dtype"):
|
|
157
|
+
return value.dtype
|
|
158
|
+
return None
|