python - 使用 Python 根据上次选择的列中提供的整数在 Postgresql 数据库中选择动态行
问题描述
我今天刚开始使用 Python,所以我处于新手级别。
我正在尝试制作一个数据库驱动的“决策树”。一旦完成,它将像在线 Python 示例中看到的“选择你自己的冒险”故事一样运行。
我在 PostgreSQL 中有一个包含以下列的表:id、textfield、nextitem
这是我要做的事情: - 脚本将从表中的某个记录开始。现在出于所有目的,我们将从 id 1 开始。我们将查询第一行(或任何可能成为未来起点的行)。因此,如果我要在 Postgres 中直接引用它,我只需 SELECT * FROM mytable 或 SELECT * FROM mytable WHERE id=1
- 如果列 [nextitem] 不为空,则继续处理列中的整数。因此,如果 SELECT * FROM mytable WHERE id=1 在 [nextitem] 中的值为“4”,则下一个查询应该是 SELECT * FROM mytable WHERE id=4。此过程将重复,直到 [nextitem] 为 NULL。
我在带有 PostgreSQL 9.6 和 psycopg2 的 Ubuntu Server 16.04.3 上使用 Python3。
我相信我需要做的是将列中的值拉出到一个变量中,然后允许 python 将其反馈给未来的查询,而不是循环它。
这是我到目前为止所拥有的(它需要大量清洁,因为我在被卡住的区域尝试了不同的东西而弄得一团糟——我的挂断似乎是将查询中的数据分离到 python 变量中并提供它回到):
import psycopg2
try:
connect_str = "dbname='mydatabase' user='myuser' host='localhost' " + \
"password='mypassword'"
# establish a connection
conn = psycopg2.connect(connect_str)
# cursor that to execute queries
cursor = conn.cursor()
# start at the beginning, select the first text field
sql = "SELECT textfield FROM mytable WHERE id=1"
cursor.execute(sql)
rows = cursor.fetchall()
print(rows)
cont = raw_input('Type Accept Continue')
# if user accepts it is ok to proceed, advance to display data from next textfield
if cont=='Accept':
print("Accepted")
sqn = "SELECT textfield, nextitem FROM mytable WHERE id=2"
cursor.execute(sqn)
rows = cursor.fetchall()
print(rows)
result_set = cursor.fetchall()
#ideally, this should grab the integer in the [nextitem] column from last query and select the row corresponding to the integer
for row in result_set:
#print the integer to test the value and make sure it is correct
print "%s" % (row["nextitem"])
#attempt to assign this integer to a variable?
x=["nextitem"]
#attempt feeding the integer previously selected in [nextitem] into the next query
sqv = "SELECT text FROM mytable WHERE id=%s"
cursor.execute(sqv,x)
result = cursor.fetchall()
print(result)
else:
print("Rejected or Not Accepted")
except Exception as e:
print("No Connection Available")
print(e)
解决方案
将您的数据库操作拆分为单独的函数。这将使程序流程更容易。
然后简单地循环,使用输入 ID 获取消息文本,显示消息,获取输入 -> 下一个 ID,重复。
您不需要“接受”条件,只需将其作为第一个文本的一部分(在 mytable.id=1 上):“输入 2 接受,q 退出”。
def openDatabase():
connect_str = "dbname='mydatabase' user='myuser' host='localhost' password='mypassword'"
try:
conn = psycopg2.connect(connect_str)
except:
sys.stderr.write("Unable to connect to database\n")
conn = None
return conn
def fetchSQL(db_conn, sql_query):
cursor = db_conn.cursor()
# start at the beginning, select the first text field
cursor.execute(sql_query)
rows = cursor.fetchall()
#print(rows)
return rows
def fetchItemText(db_conn, item_index):
query = "SELECT textfield FROM mytable WHERE id=" + str(item_index)
rows = fetchSQL(db_conn, query)
if (len(rows) > 0):
return rows[0][0] # Maybe just be rows[0]? Coding of the top of my head
else:
return ""
### Main
db = openDatabase()
if (db != None):
# do some stuff
finished = False
user_choice = 1
# Prompt the user with the text, get their input
while (not finished):
prompt = fetchItemText(db, user_choice)
user_choice = raw_input(prompt + "\n>>>")
if (user_choice == 'q'):
finished = True
else:
user_choice = int(user_choice) # TODO handle errors
推荐阅读
- mongodb - MongoExpress 显示“无法读取未定义的属性 'listDatabases'”错误
- c++ - C ++如何将Parent传递给需要Child的函数?
- c# - 使用带有 C# 的 AWS S3 程序集的问题
- c++ - 你如何反转strong_ordering?
- php - 将小数添加到脚本中的 PHP 输出
- swift - 首次调用信号时如何使用 Dispatch_Sempahore
- javascript - Telegraf 和云功能:如何阻止 Telegram Bot 接收无休止的旧更新
- javascript - 如何以角度在 ag grid masterdetail 的 detailCellRendererParams 内进行控制台
- shell - 如何使用 shell 脚本过滤字符串
- karate - 空手道加特林:未获取对功能文件的更改