代码之家  ›  专栏  ›  技术社区  ›  hwjp

如何使用sqlalchemy利用sqlite清单类型/类型关联?

  •  1
  • hwjp  · 技术社区  · 15 年前

    我喜欢sqlite的清单类型/类型关联的想法:

    http://www.sqlite.org/datatype3.html

    从本质上讲,如果我将列的关联设置为“numeric”,它将使用duck类型的整数或float来存储它们,但如果我愿意,仍然允许我存储字符串。在我看来,对于一个列来说,这是最好的“默认”类型,因为我不能提前确定要在其中存储什么数据。

    所以我走了:

    metadata = MetaData()
    new_table = Table(table_name, metadata )
    for col_name in column_headings:
        new_table.append_column(Column(col_name, 
                                       sqlite.NUMERIC, #this should duck-type numbers but can handle strings as well
                                       primary_key=col_name in primary_key_columns))
    new_table.create(self.engine, checkfirst=False)
    

    但是,当我尝试在表中存储一些字符串值(例如“abc”)时,sqlalchemy失败了:

      File "[...]\sqlalchemy\processors.py", line 79, in to_float
        return float(value)
    ValueError: invalid literal for float(): abc
    

    嘘,嘘。那么,我有没有办法说服sqlalchemy让sqlite来打字呢?或许我可以使用sqlalchemy.types中的类型,而不是sqlachemy.dialongs.sqlite?

    2 回复  |  直到 15 年前
        1
  •  1
  •   hwjp    15 年前

    好吧,我想到的是:

    根据定义自定义列类型 http://www.sqlalchemy.org/docs/reference/sqlalchemy/types.html#custom-types

    文档和一些试用版的结合;错误告诉我:

    class MyDuckType(sqlalchemy.types.TypeDecorator):
        """
        SQLALchemy custom column type, designed to let sqlite handle the typing 
        using 'numeric affinity' which intelligently handles both numbers and strings
        """
        impl = sqlite.NUMERIC
    
        def bind_processor(self, dialect):
            #function for type coercion during db write
            return None #ie pass value as-is, let sqlite do the typing
    
        def result_processor(self, dialect, coltype):
            #function for type coercion during db read
            return None #ie pass value as sqlite has stored it, should be ducktyped already
    
        def process_bind_param(self, value, dialect):
            #any changes to an individual value before store in DN
            return value
    
        def process_result_value(self, value, dialect):
            #any changes to an individual value after retrieve from DB
            return value
    
        def copy(self):
            #not quite sure what this is for
            return MyDuckType()
    

    当前的sqlalchemy方言类型返回到bind\u处理器中的\u float,这就是我之前得到错误的原因。i、 m.v.v.h.o.,这是个虫子。

    对于我的加分:在my metadata.reflect()代码中将列类型手动设置为MyDuckType:

    def get_database_tables(engine):
        meta = MetaData()
        meta.reflect(bind=engine)
        tables = meta.raw_tables
        for tbl in tables.values():
            for col in tbl.c:
                col.type = MyDuckType()
        return tables
    

    似乎对我有用。有什么建议/改进吗?

        2
  •  0
  •   dan04    15 年前

    基本上,如果我设置列的 作为“数字”,它将回避 键入整数或浮点数来存储它们 如果我愿意的话。

    123 '123' .