繁体   English   中英

SQLAlchemy 不匹配列与 orm 查询

[英]SQLAlchemy mismatches column with orm query

我在 Flask 应用程序中具有订阅和订阅者表/模型的简单关系,其中我使用 SQLAlchemy 在开发期间本地查询 SQLite 数据库。

订阅通过如下定义的subscriber_id字段与订阅者建立关系:

subscriber_id = Column(db.Integer, ForeignKey('subscriber.id'))

这两个对象都有一个定义为String(36)的字段,当它们在数据库中创建时,我正在将 UUID4 字符串写入其中。 它们分别是subscription_idsubscriber_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_id1 ,从数据库中检索订阅者。

然而,第二个查询不起作用,即使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 实现完全“不同”:

  1. SQLite 不严格执行列类型,它只识别列"affinities" 因此,可以将列声明为INT ,在其中插入一个字符串(如 UUID 的字符串表示),并且 SQLite 不一定会引发错误。

  2. SQLite 接受外键约束声明,但默认忽略它们 在使用 SQLite 并期望外键“正常工作”时,这可能会导致混淆。

这两种行为都对这个问题起作用。 将 (UUID) 字符串插入到原本应为 integer 的列中时出现编码错误,并且未强制执行外键约束导致 go 的错误未被注意。

道德:使用 SQLite 并欣赏它所能提供的东西,但也要注意它的特殊“个性”(就像任何其他 SQL 方言一样)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM