e-data 2.0.2.dev136__py3-none-any.whl → 2.0.2.dev137__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: e-data
3
- Version: 2.0.2.dev136
3
+ Version: 2.0.2.dev137
4
4
  Summary: Python library for managing spanish energy data from various web providers
5
5
  Author-email: VMG <vmayorg@outlook.es>
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -697,7 +697,7 @@ Requires-Dist: pydantic<3,>=2.10
697
697
  Requires-Dist: python_dateutil<3,>=2.8
698
698
  Requires-Dist: Requests<3,>=2.31
699
699
  Requires-Dist: SQLAlchemy[asyncio]<3,>=2.0
700
- Requires-Dist: sqlmodel<0.0.45,>=0.0.22
700
+ Requires-Dist: sqlmodel<0.1,>=0.0.45
701
701
  Requires-Dist: typer<1,>=0.12
702
702
  Requires-Dist: aiosqlite<1,>=0.21
703
703
  Dynamic: license-file
@@ -1,4 +1,4 @@
1
- e_data-2.0.2.dev136.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
1
+ e_data-2.0.2.dev137.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
2
2
  edata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  edata/cli.py,sha256=CsBYDggt0grkLb4cebrckOvJyHr9PaGTnlWqT4yjuFo,5215
4
4
  edata/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -7,7 +7,7 @@ edata/core/const.py,sha256=X9J2f7lt9jXJnghqz0JFi-J7USa3xlYvbuiki70eHNE,43
7
7
  edata/core/utils.py,sha256=uQX8GmNjuhof56jiXXoV-Fk-d590OuIoBJbM9ymZyV8,3194
8
8
  edata/database/__init__.py,sha256=HP_pDbGLzeMY9Ufm_Dps5cxzW_3YTonT8w8dstG558c,46
9
9
  edata/database/controller.py,sha256=bI3cE1Q4SK9U1Eep_61EhlmyVjgYH87F5lfBLhwSpmg,23211
10
- edata/database/models.py,sha256=tSkxf2OKgT1m2F1td3j3GtYcboUtSuYbhnHWQtpvJuY,5525
10
+ edata/database/models.py,sha256=WWZHYgFBgSDqHORxw5z4Vip7HvorMcQbt9oCpV61NJA,5780
11
11
  edata/database/queries.py,sha256=XziDSG2V-PVFmvRkj8UrEvgrc9Qc-ShhnxgsPHIsyik,8304
12
12
  edata/database/utils.py,sha256=V-FJfyAh8YJBGHB85BbWtG3Ilq09pM9Gl-L86TffB4g,1062
13
13
  edata/database/migrations/__init__.py,sha256=P8VXZzfyceOV3GknYXif2HEMB8Bo4B7f7vKdIC02ZO0,1203
@@ -24,14 +24,14 @@ edata/services/bill_service.py,sha256=KAM78u7TpoVF-KTlB7bqj2Kp-rJERiPPoGTJCc-7rM
24
24
  edata/services/data_service.py,sha256=JJCdivjrwNt3aLhz3uMBWv06y-EL7UiK2G5EBr97l_8,19374
25
25
  edata/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
26
  edata/tests/test_completion.py,sha256=-iyVt-juU3U1HqMuLUJXJthil2-n_4ddWiJq2GwnXTo,3551
27
- edata/tests/test_controller.py,sha256=E1Blvel2dtS8CiyxErP4V_wpzWlEcxTYA1gW1f8-Gg4,3449
27
+ edata/tests/test_controller.py,sha256=YvilJ9cIpjhdGGtVJtlEevhRL7IHAVnU0At7AmxM5_8,3983
28
28
  edata/tests/test_datadis_connector.py,sha256=8Xet2M2eG-kMhiRDTCSH0R5nYO2oIpQTPOuTZKMKoLo,12538
29
29
  edata/tests/test_incremental.py,sha256=dn1LRgjBi2HuNYELPKDVdZQlS01hk4lsP9L-vyvtEHo,3479
30
30
  edata/tests/test_migrations.py,sha256=3Io2nokZVdv2xU9fCZCMIvwAwPVtGc0UivClSouP3pw,6418
31
31
  edata/tests/test_redata_connector.py,sha256=SBvxsma5t-qvz2drxNisNM2P1STTurqEs1TSDgwaPJ8,508
32
32
  edata/tests/test_services.py,sha256=Ya5cbADHj1Qsffb_IuMeDD0BViz8nqrgwazUWK0-hRc,8297
33
33
  edata/tests/test_utils.py,sha256=h6yBzT7j3eA42zbXJ-AK9lXcZkjCMf16wnob1oqGvUE,2307
34
- e_data-2.0.2.dev136.dist-info/METADATA,sha256=YZbWL0ZGXBHvfFBODBeXBwD8CcQHH5VXqYqY_NV42GE,48087
35
- e_data-2.0.2.dev136.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
36
- e_data-2.0.2.dev136.dist-info/top_level.txt,sha256=Ez-fReWtUVTMcFuH0dzCnoKIgMBHgjLaBuba8QiKC7g,6
37
- e_data-2.0.2.dev136.dist-info/RECORD,,
34
+ e_data-2.0.2.dev137.dist-info/METADATA,sha256=-7nOw3zSVBn4BVOgnmEXPt44pUE_qauv2ZZ2yjDjXt4,48084
35
+ e_data-2.0.2.dev137.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
36
+ e_data-2.0.2.dev137.dist-info/top_level.txt,sha256=Ez-fReWtUVTMcFuH0dzCnoKIgMBHgjLaBuba8QiKC7g,6
37
+ e_data-2.0.2.dev137.dist-info/RECORD,,
edata/database/models.py CHANGED
@@ -1,6 +1,7 @@
1
1
  import typing
2
2
  from datetime import datetime as dt
3
3
 
4
+ from pydantic import NaiveDatetime
4
5
  from sqlmodel import AutoString, Column, Field, Index, SQLModel, UniqueConstraint
5
6
 
6
7
  from edata.database.utils import PydanticJSON
@@ -27,8 +28,8 @@ class SupplyModel(SQLModel, table=True):
27
28
  cups: str = Field(default=None, primary_key=True)
28
29
  data: Supply = Field(sa_column=Column(PydanticJSON(Supply)))
29
30
  version: int = Field(default=1)
30
- created_at: dt = Field(default_factory=_now, nullable=False)
31
- updated_at: dt = Field(
31
+ created_at: NaiveDatetime = Field(default_factory=_now, nullable=False)
32
+ updated_at: NaiveDatetime = Field(
32
33
  default_factory=_now, nullable=False, sa_column_kwargs={"onupdate": dt.now}
33
34
  )
34
35
 
@@ -44,12 +45,12 @@ class ContractModel(SQLModel, table=True):
44
45
 
45
46
  id: int | None = Field(default=None, primary_key=True)
46
47
  cups: str = Field(foreign_key="supply.cups", index=True)
47
- date_start: dt = Field(index=True)
48
+ date_start: NaiveDatetime = Field(index=True)
48
49
  data: Contract = Field(sa_column=Column(PydanticJSON(Contract)))
49
50
 
50
51
  version: int = Field(default=1)
51
- created_at: dt = Field(default_factory=_now, nullable=False)
52
- updated_at: dt = Field(
52
+ created_at: NaiveDatetime = Field(default_factory=_now, nullable=False)
53
+ updated_at: NaiveDatetime = Field(
53
54
  default_factory=_now, nullable=False, sa_column_kwargs={"onupdate": dt.now}
54
55
  )
55
56
 
@@ -71,13 +72,13 @@ class EnergyModel(SQLModel, table=True):
71
72
  id: int | None = Field(default=None, primary_key=True)
72
73
  cups: str = Field(foreign_key="supply.cups", index=True)
73
74
  delta_h: float
74
- datetime: dt = Field(index=True)
75
+ datetime: NaiveDatetime = Field(index=True)
75
76
 
76
77
  data: Energy = Field(sa_column=Column(PydanticJSON(Energy)))
77
78
 
78
79
  version: int = Field(default=1)
79
- created_at: dt = Field(default_factory=_now, nullable=False)
80
- updated_at: dt = Field(
80
+ created_at: NaiveDatetime = Field(default_factory=_now, nullable=False)
81
+ updated_at: NaiveDatetime = Field(
81
82
  default_factory=_now, nullable=False, sa_column_kwargs={"onupdate": dt.now}
82
83
  )
83
84
 
@@ -93,13 +94,13 @@ class PowerModel(SQLModel, table=True):
93
94
 
94
95
  id: int | None = Field(default=None, primary_key=True)
95
96
  cups: str = Field(foreign_key="supply.cups", index=True)
96
- datetime: dt = Field(index=True)
97
+ datetime: NaiveDatetime = Field(index=True)
97
98
 
98
99
  data: Power = Field(sa_column=Column(PydanticJSON(Power)))
99
100
 
100
101
  version: int = Field(default=1)
101
- created_at: dt = Field(default_factory=_now, nullable=False)
102
- updated_at: dt = Field(
102
+ created_at: NaiveDatetime = Field(default_factory=_now, nullable=False)
103
+ updated_at: NaiveDatetime = Field(
103
104
  default_factory=_now, nullable=False, sa_column_kwargs={"onupdate": dt.now}
104
105
  )
105
106
 
@@ -120,14 +121,14 @@ class StatisticsModel(SQLModel, table=True):
120
121
 
121
122
  id: int | None = Field(default=None, primary_key=True)
122
123
  cups: str = Field(foreign_key="supply.cups", index=True)
123
- datetime: dt = Field(index=True)
124
+ datetime: NaiveDatetime = Field(index=True)
124
125
  type: typing.Literal["day", "month"] = Field(index=True, sa_type=AutoString)
125
126
  complete: bool = Field(False)
126
127
  data: Statistics = Field(sa_column=Column(PydanticJSON(Statistics)))
127
128
 
128
129
  version: int = Field(default=1)
129
- created_at: dt = Field(default_factory=_now, nullable=False)
130
- updated_at: dt = Field(
130
+ created_at: NaiveDatetime = Field(default_factory=_now, nullable=False)
131
+ updated_at: NaiveDatetime = Field(
131
132
  default_factory=_now, nullable=False, sa_column_kwargs={"onupdate": dt.now}
132
133
  )
133
134
 
@@ -137,12 +138,12 @@ class PVPCModel(SQLModel, table=True):
137
138
  __tablename__ = "pvpc" # type: ignore
138
139
 
139
140
  id: int | None = Field(default=None, primary_key=True)
140
- datetime: dt = Field(index=True, unique=True)
141
+ datetime: NaiveDatetime = Field(index=True, unique=True)
141
142
  data: EnergyPrice = Field(sa_column=Column(PydanticJSON(EnergyPrice)))
142
143
 
143
144
  version: int = Field(default=1)
144
- created_at: dt = Field(default_factory=_now, nullable=False)
145
- updated_at: dt = Field(
145
+ created_at: NaiveDatetime = Field(default_factory=_now, nullable=False)
146
+ updated_at: NaiveDatetime = Field(
146
147
  default_factory=_now, nullable=False, sa_column_kwargs={"onupdate": dt.now}
147
148
  )
148
149
 
@@ -163,14 +164,14 @@ class BillModel(SQLModel, table=True):
163
164
 
164
165
  id: int | None = Field(default=None, primary_key=True)
165
166
  cups: str = Field(foreign_key="supply.cups", index=True)
166
- datetime: dt = Field(index=True)
167
+ datetime: NaiveDatetime = Field(index=True)
167
168
  type: typing.Literal["hour", "day", "month"] = Field(index=True, sa_type=AutoString)
168
169
  complete: bool = Field(False)
169
170
  confhash: str
170
171
  data: Bill = Field(sa_column=Column(PydanticJSON(Bill)))
171
172
 
172
173
  version: int = Field(default=1)
173
- created_at: dt = Field(default_factory=_now, nullable=False)
174
- updated_at: dt = Field(
174
+ created_at: NaiveDatetime = Field(default_factory=_now, nullable=False)
175
+ updated_at: NaiveDatetime = Field(
175
176
  default_factory=_now, nullable=False, sa_column_kwargs={"onupdate": dt.now}
176
177
  )
@@ -6,6 +6,8 @@ from datetime import datetime, timedelta
6
6
 
7
7
  import pytest
8
8
  import pytest_asyncio
9
+ from sqlalchemy import DateTime
10
+ from sqlmodel import SQLModel
9
11
 
10
12
  from edata.database.controller import EdataDB
11
13
  from edata.models import Bill, Energy, Supply
@@ -106,3 +108,16 @@ async def test_concurrent_first_calls_do_not_race_index_creation(db: EdataDB) ->
106
108
  "SELECT name FROM sqlite_master WHERE name='ix_energy_cups_datetime'"
107
109
  )
108
110
  assert result.first() is not None
111
+
112
+
113
+ def test_datetime_columns_are_naive() -> None:
114
+ # the supply timezone is unknown, so datetimes are stored as-is (naive);
115
+ # plain ``datetime`` fields map to UTC-aware columns on sqlmodel>=0.0.45
116
+ columns = [
117
+ column
118
+ for table in SQLModel.metadata.sorted_tables
119
+ for column in table.columns
120
+ if isinstance(column.type, DateTime)
121
+ ]
122
+ assert len(columns) == 20
123
+ assert all(column.type.timezone is False for column in columns)