用例
我将 SQLAlchemy 和 SQLite 用于独立应用程序(非 Web),我需要将数值范围存储在数据库中。我通过在 SQLite 中保存每个范围的开始和结束来做到这一点,如下所示:
[[float("-inf"), 0], [1, 1000],..., [9999, 12000], [12001, float("inf")]]
在最终的应用程序中,我需要确定任意值number
落在哪个范围内。我正在做如下的事情:
...
for range_ in ranges:
range_start, range_end = range_
if range_start <= number <= range_end:
return range_
...
number
可以是任何整数或无穷大,因此 db 中的范围必须从负无穷大延伸到正无穷大
问题
以下代码工作正常
import sqlalchemy as sa
from sqlalchemy.orm import declarative_base, sessionmaker, scoped_session
Base = declarative_base()
class MyMappedClass(Base):
__tablename__ = "my_table"
id = sa.Column(sa.Integer, primary_key=True)
ranges = sa.Column(sa.JSON)
if __name__ == "__main__":
engine = sa.create_engine("sqlite://", future=True)
Session = scoped_session(sessionmaker(bind=engine))
session = Session()
Base.metadata.create_all(session.bind)
mapped_class = MyMappedClass(
ranges=[[float("-inf"), 1], [1, float("inf")]],
)
with session:
session.add(mapped_class)
session.commit()
但是当我添加一个CheckConstraint
调用时,json_array_length(ranges)
我得到一个malformed JSON
错误:
...
ranges = sa.Column(
sa.JSON,
sa.CheckConstraint("json_array_length(ranges) >= 2"),
)
...
追溯:
...
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) malformed JSON
...
我确认[[float("-inf"), 1], [1, float("inf")]]
没有通过更改CheckConstraint
to将其转换为有效的 JSON,json_valid(ranges)
并且仅当列中存在无穷大时它才会失败。
我必须能够将CheckConstraint
s 添加到ranges
列中。我需要对其他列执行数据验证步骤。其中的细节很复杂,超出了这个问题的范围。
解决方法
我想我可以通过这样替换来解决这个float("inf")
问题"inf"
mapped_class = MyMappedClass(
ranges=[["-inf", 1], [1, "inf"]],
)
我可以确定任意的范围,number
例如:
...
for range_ in ranges:
range_start, range_end = range
if float(range_start) <= number <= float(range_end):
return range_
...
但现在我在列中混合了类型,我更喜欢只存在数字。
回到问题
有没有办法在 JSON1 列中存储无穷大?如果有其他数据库支持数组中的无穷大(适用于独立应用程序),请分享。理想情况下,SQLAlchemy 支持这个数据库。