【问题标题】:How to use ARRAY of INET in flask-sqlalchemy?如何在flask-sqlalchemy中使用INET的ARRAY?
【发布时间】:2016-05-13 08:26:50
【问题描述】:

我的烧瓶应用程序中有一个带有 ips 字段数组的用户模型。我想使用 inet 类型的 postgresql 数组:

from flask.ext.sqlalchemy import SQLAlchemy
from sqlalchemy.dialects.postgresql import ARRAY, INET, Integer, Unicode, Column
db = SQLAlchemy()

class User(db.Model):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    login = Column(Unicode(15))
    password = Column(Unicode(34))
    name = Column(Unicode(100))
    permitted_ips = Column(ARRAY(INET))

但是当我进行查询时,我得到了错误的答案:

user = User.query.get(84)
print user.permitted_ips
#['{', '1', '7', '2', '.', '2', '0', '.', '2', '5', '.', '2', ',', '1', '7', '2', '.', '2', '0', '.', '2', '5', '.', '3', '}']

而不是 ['172.20.25.2', '172.20.25.3']。当前版本的 sqlalchemy 是 0.9.10。我尝试了最新的,但结果是一样的。有办法解决吗?

【问题讨论】:

    标签: postgresql flask sqlalchemy


    【解决方案1】:

    我发现数组不会自动解析,所以你需要用 psycopg2 库创建一个generic type caster

    # needed imports
    from psycopg2 import STRING
    from psycopg2.extensions import register_type, new_array_type
    

    注册数组类型,一次性完成。

    # to see the oid of inet. As pointed out by @univerio the oid should never             
    # change, so you don't need to fetch it every time your app starts.
    tp = db.engine.execute("select typarray from pg_type where typname = 'inet'")
    print(tp.fetchone())
    # (1041,)
    
    # registering the array type
    register_type(new_array_type((1041,), 'INET[]', STRING))
    

    现在您可以获取数组,它会被正确解析。

    # fetch data
    ips = db.engine.execute("select permitted_ips from users where id = 1")
    print(ips.fetchone()[0])
    # ['172.20.25.2', '172.20.25.3'].
    

    【讨论】:

    • 注册数组类型绝对比临时解析“错误”字符串更干净。
    • 你的意思是更安全?我不是专家,你能解释一下吗?
    • 不,它更干净。如果您必须在任何地方进行这种临时转换,您需要访问user.permitted_ips,那么在您将它设置在对象上之前自动完成它不是很好吗?同样的原因,它不只是给你整数作为字符串,并要求你每次都做int(user.id)
    • 谢谢,现在我明白了。当我说这更清洁时,因为我建议使用 SQL 而不是 ORM 本身,我认为这很混乱......无论如何,也许有办法用 sqlalchemy 做到这一点,我会做我的研究,再次感谢!
    • 我明白了。内置类型的 oid 永远不会改变,因此您不必在每次应用启动时都从 PostgreSQL 获取它。
    猜你喜欢
    • 2022-07-09
    • 2021-12-27
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    • 2012-08-16
    • 2019-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多