[英]SQLAlchemy mismatches column with orm query
我在 Flask 应用程序中具有订阅和订阅者表/模型的简单关系,其中我使用 SQLAlchemy 在开发期间本地查询 SQLite 数据库。
订阅通过如下定义的subscriber_id
字段与订阅者建立关系:
subscriber_id = Column(db.Integer, ForeignKey('subscriber.id'))
这两个对象都有一个定义为String(36)
的字段,当它们在数据库中创建时,我正在将 UUID4 字符串写入其中。 它们分别是subscription_id
和subscriber_id
,如下所示:
@dataclass
class Subscription(db.Model):
__tablename__ = 'subscription'
subscription: str
subscriber: str
id = Column(db.Integer, primary_key=True)
subscription_id = Column(
db.String(36),
default=generate_uuid, # a function that returns a uuid4
unique=True
)
subscriber_id = Column(db.Integer, ForeignKey('subscriber.id'))
在使用 PyTest 执行测试期间,我遇到了一个奇怪的行为,其中Subscription
实例的subscriber_id
返回的不是 integer,如 class 中定义的那样,而是一个 UUID。
该测试运行一个查询订阅者的方法,然后尝试获取其订阅:
subscriber = Subscriber.query.filter(
Subscriber.subscriber_id == subscriber_id
).first()
assert subscriber is not None
subscriptions = Subscription.query.filter(
Subscription.subscriber_id == subscriber_id
).all()
执行期间subscriber_id
为1
,从数据库中检索订阅者。
然而,第二个查询不起作用,即使subscriber_id
是订阅者id
的外键。
如果我用另一个没有过滤器的查询替换第二个查询,它可以工作。 但后来我看到了这个问题,返回的subscriber_id
ID 不是 integer,而是 UUID:
raise Exception(Subscription.query.first().subscriber_id)
subscriptions = Subscription.query.filter(
Subscription.subscriber_id == subscriber_id
).all()
> raise Exception(Subscription.query.first().subscriber_id)
E Exception: 59ebfdd6-1cbc-4748-94e1-955ef55c380c
SQLAlchemy 有没有我在这里没有考虑的特殊行为? 也许是表/字段的命名约定?
与 SQLite 一样精彩,它有两个功能使其与大多数其他 SQL 实现完全“不同”:
SQLite 不严格执行列类型,它只识别列"affinities" 。 因此,可以将列声明为INT
,在其中插入一个字符串(如 UUID 的字符串表示),并且 SQLite 不一定会引发错误。
SQLite 接受外键约束声明,但默认忽略它们。 在使用 SQLite 并期望外键“正常工作”时,这可能会导致混淆。
这两种行为都对这个问题起作用。 将 (UUID) 字符串插入到原本应为 integer 的列中时出现编码错误,并且未强制执行外键约束导致 go 的错误未被注意。
道德:使用 SQLite 并欣赏它所能提供的东西,但也要注意它的特殊“个性”(就像任何其他 SQL 方言一样)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.