3

我有一个表“城市”定义为:

CREATE TABLE `City` (
  `id` int(11) NOT NULL,
  `lat` decimal(9,6) default NULL,
  `long` decimal(9,6) default NULL,
  `lm_index` int(11) default NULL,
  `num_business` int(11) default NULL,
  `postal_code` varchar(16) default NULL,
PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

我使用 python 和 SQLAlchemy 来映射这个表:

Base = declarative_base(engine)

class City(Base):
    ''''''
    __tablename__ = 'City'
    __table_args__ = {'autoload':True}
    def __init__(self, id, lat, long, lm_index, numbiz, postal):
        self.id = id
        self.lat = lat
        self.long = long
        self.lm_index = lm_index
        self.num_business = numbiz
        self.postal_code = postal

如果我正确理解了 python 十进制包,这应该可以工作:

from decimal import *

getcontext().prec = 6
lat = 12.11111111
long = 46.2222222

city = City(1, Decimal(str(lat)), Decimal(str(long)), 0, 0, 0)

但是,当我不调用 Decimal() 时,我仍然会遇到相同的错误:

Warning: Data truncated for column 'lat' at row 1

我在这里做错了什么?

4

1 回答 1

3

我的猜测是,因为您要发送 的实例Decimal,所以latorlong字段将被转换为类似实例的字符串表示形式。同样,我不确定。您可以使用它pdb来调试它。

无论如何,有更好的方法来处理通过 SQLAlchemy中的DECIMAL字段。MySQL而不是自己处理十进制处理,您可以让 sqlalchemy 处理它 -

从 sqlalchemy.ext.declarative 导入 declarative_base Base = declarative_base()

class City(Base):
    __tablename__ = 'City'
    __table_args__ = {'autoload':True}

    id = Column(Integer, primary_key=True)
    lat =  Column(Numeric(precision=9, scale=6))
    long =  Column(Numeric(precision=9, scale=6))
    ...

Numeric字段decimal.Decimal默认返回对象,根据需要应用转换。

然后你可以启动它 -

city = City(lat=12.11111111, long=46.2222222, ...)

如果您覆盖__init__(),那么您可以像 一样启动它City(12.1111, 46.2222),但我更喜欢保留列名,这样您一眼就知道哪个字段正在获取什么,而不是每次都计算值的数量。

我还没有测试过代码,但它应该可以工作。尝试。

于 2013-05-10T20:22:41.047 回答