Python3.6函数未调用

时间:2018-11-22 16:38:07

标签: python postgresql psycopg2

我正在使用RESTFlask-Rebar在Python 3.6中开发一个PostgreSQL API,尝试使用psycopg2同时执行一些查询时遇到了麻烦。

更具体地说,我执行一个查询,并要求此查询中的id值用于下一个查询。第一个查询成功返回期望值,但是调用后续查询的函数甚至没有执行。

以下是负责调用查询功能的功能:

psql = PostgresHandler()

user_ids = [1, 5, 9]
horse = {"name": "Adam", "age": 400}

def createHorseQuery(user_ids, horse):
    time_created = strftime("%Y-%m-%dT%H:%M:%SZ")

    fields, values = list(), list()

    for key, val in horse.items():
        fields.append(key)
        values.append(val)

    fields.append('time_created')
    values.append(time_created)

    fields = str(fields).replace('[', '(').replace(']', ')').replace("'", "")
    values = str(values).replace('[', '(').replace(']', ')')

    create_horse_query = f"INSERT INTO horse {fields} VALUES {values} RETURNING horse_id;"

    horse_id = None
    for h_id in psql.queryDatabase(create_horse_query, returnInsert=True):
        horse_id = h_id

    link_user_query = ''

    for u_id in user_ids:
        link_user_query += f"INSERT INTO user_to_horse (user_id, horse_id) VALUES ({u_id}, {horse_id['horse_id']});"

    psql.queryDatabase(link_user_query)

    return horse_id, 201

这是PostgresHandler()类,其中包含函数queryDatabase

class PostgresHandler(object):
    def __init__(self):
        self.connectToDatabase()

    def connectToDatabase(self):
        self.connection = psycopg2.connect(
            host        = '...',
            user        = '...',
            password    = '...',
            database    = '...'
        )

    def queryDatabase(self, query, returnInsert=False):
        cursor = self.connection.cursor(cursor_factory=RealDictCursor)

        cursor.execute(query)

        if "SELECT" in query.upper():
            for result in cursor.fetchall():
                yield result
        elif "INSERT" in query.upper():
            if returnInsert:
                for result in cursor.fetchall():
                    yield result

            self.connection.commit()

        cursor.close()

我可以通过手动查询数据库并与返回值psql.queryDatabase(create_horse_query, returnInsert=True)进行比较来验证h_id操作是否成功。

我可以验证是否创建了link_user_query并包含打印所期望的user_idshorse_id。我知道所生成的查询是可以的,因为我已经在数据库中对此进行了手动测试。

psql.queryDatabase(link_user_query)函数的非常顶部处,似乎从未真正调用在行queryDatabase上调用的函数作为打印语句。 / p>

我尝试在两个查询函数调用之间进行延迟,并与每个函数调用初始化一个新的连接,但许多其他事情无济于事,我对此感到很沮丧。任何见解都将不胜感激。

编辑:仅供参考,createHorseQuery函数成功返回并按预期显示两个返回值。

1 个答案:

答案 0 :(得分:1)

您的代码中的

queryDatabase是生成器,因为它包含一个yield语句。生成器仅在您对其进行迭代时才实际执行操作(即导致__next__()被调用)。请考虑以下内容:

def gen():
    print("Gen is running!")
    yield "Gen yielded: hello"
    print("Gen did: commit")

print("***Doing stuff with b***")
b = gen()
for a in b:
    print(a)

print("***Doing stuff with c***")
c = gen()

print("***Done***")

输出为:

***Doing stuff with b***
Gen is running!
Gen yielded: hello
Gen did: commit
***Doing stuff with c***
***Done***

当我们调用gen()创建c时,我们实际上并没有运行它,只是将其实例化为生成器。

我们可以通过多次调用__next__()来强制其运行:

c.__next__()
try:
    c.__next__()
except StopIteration:
    print("Iteration is over!")

输出:

Gen is running!
Gen did: commit
Iteration is over!

但是,实际上,您可能不应该在从未打算从中使用yield的情况下使用这样的生成器。您可以考虑添加一个新函数,该函数不是名为insertSilently(或类似名称)的生成器。