Sqlalchemy有时无法获取数据

时间:2014-01-14 02:05:35

标签: python mysql sqlalchemy openstack

我有一个名为weixin_db的数据库,其中有一个名为nvi_instance的表。这是详细信息:

mysql> desc instance;
+--------------+------------------+------+-----+---------+----------------+
| Field        | Type             | Null | Key | Default | Extra          |
+--------------+------------------+------+-----+---------+----------------+
| id           | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| guest_uuid   | varchar(255)     | NO   |     | NULL    |                |
| logical_ipv4 | varchar(255)     | NO   |     | NULL    |                |
| logical_ipv6 | varchar(255)     | NO   |     | NULL    |                |
+--------------+------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

我用它来连接数据库:

def get_engine():
    global engine
    global conn
    if engine:
        if not conn:
            conn = engine.connect()
        return (engine, conn)

    conn_str = ''.join((conf["db_dialect"], "://", conf["db_user"], ":", conf["db_pwd"], "@",
                    conf["db_host"], ":", conf["db_port"], "/", conf["db_name"]))
    engine = sqlalchemy.create_engine(conn_str)
    conn = engine.connect()
    return (engine, conn)

这是配置:

[db]
db_dialect = mysql
db_host = localhost
db_port = 3306
db_name = weixin_db
db_user = root
db_pwd = 9f71f05812f44553

当我使用sel_nvi_ip从以下代码获取数据时,有时我无法获取数据,有时我可以从数据库中获取数据:

class Nvi_Instance(object):
"""
inter_clouds
"""
    def __init__(self):
        self.engine, self.conn = get_engine()

    def sel_nvi_ipv4(self, guest_uuid):
        s =   sqlalchemy.select([weixinverify.c.logical_ipv4]).where(weixinverify.c.guest_uuid == guest_uuid)
        return self.conn.execute(s)

    def sel_nvi_ipv6(self, guest_uuid):
        s =       sqlalchemy.select([weixinverify.c.logical_ipv6]).where(weixinverify.c.guest_uuid == guest_uuid)
        return self.conn.execute(s)

底层代码是 sel_nvi_ipv4和sel_nvi_ipv6

        value = {}
        from horizon.conf import nvi_db
        nvi = nvi_db.Nvi_Instance()

        value['id'] = 0
        try:
            value['ipv4'] = nvi.sel_nvi_ipv4(id).fetchone().values()[0]
            value['ipv6'] = nvi.sel_nvi_ipv6(id).fetchone().values()[0]
        except Exception as e:
            value['ipv4'] = None
            value['ipv6'] = None
        return {'getip': value}

异常e是:

'NoneType' object has no attribute 'values'

我的配置有问题还是出了什么问题? 我做service openstack-nova-api之后一切顺利。但几分钟后,nvi.sel_nvi_ip(id).fetchone()返回None而不是数据库中的数据。有什么问题吗?有人可以告诉我为什么吗?

1 个答案:

答案 0 :(得分:0)

更新回答:

你的函数get_engine返回引擎和连接的元组:

def get_engine():
    # ....
    return (engine, conn)

但是在Nvi_Instance中你没有解包这个元组:

class Nvi_Instance(object):
    def __init__(self):
        self.conn = get_engine()   # self.conn == (engine, conn), not just conn !!!

    def sel_nvi_ip(self, guest_uuid):
        # s = ...
        return self.conn.execute(s)
        # You try to execute query on tuple, not on connection!

然后你在try-except中调用它并静默地吞下任何异常(不要这样做):

try:
    value['ipv4'],value['ipv6'] = nvi.sel_nvi_ip(id).fetchone()        
except:
    # Here you catch: AttributeError: 'tuple' object has no attribute 'execute'
    value['ipv4'] = None
    value['ipv6'] = None
return {'getip': value}

所以你得到的是None,而不是来自DB的数据。

其他更新:

将客户端代码的返回值检查移动到Nvi_Instance:

会更好
def sel_nvi_ip(self, guest_uuid):
    s = sqlalchemy.select([weixinverify.c.logical_ipv4, weixinverify.c.logical_ipv6]).where(weixinverify.c.guest_uuid == guest_uuid)
    result = self.conn.execute(s).first()
    return result.values() if result is not None else (None, None)

然后在客户端代码中你必须写:

value['ipv4'], value['ipv6'] = nvi.sel_nvi_ip(id)
return {'getip': value}