Python &引用;名称错误:名称'&书信电报;表名>';“未定义”;在SQLAlchemy中导入数据时

Python &引用;名称错误:名称'&书信电报;表名>';“未定义”;在SQLAlchemy中导入数据时,python,database,sqlalchemy,relational-database,Python,Database,Sqlalchemy,Relational Database,尝试使用SQLAlchemy表达式语言将JSON文件中的用户数据导入数据库时,出现以下错误: name错误:未定义名称“用户” 回溯如下: Traceback (most recent call last): File "C:\Users\lmills\MyProject\Database-Configuration\CreateTable.py", line 43, in <module> importData.userDataImport() File

尝试使用SQLAlchemy表达式语言将JSON文件中的用户数据导入数据库时,出现以下错误:
name错误:未定义名称“用户”

回溯如下:

Traceback (most recent call last):
  File     "C:\Users\lmills\MyProject\Database-Configuration\CreateTable.py", line 43, in <module>
    importData.userDataImport()
  File      "C:\Users\lmills\MyProject\Database-Configuration\importData.py", line 11, in userDataImport
    conn.execute(users.insert(), userid = userData[i]['userid'], altuid = userData[i]['altuid'], lname = userData[i]['lname'], fname = userData[i]['fname'], phoneNum = userData[i]['phoneNum'], emailAddr = userData[i]['emailAddr'])
NameError: name 'users' is not defined
然后,我尝试在importData.py文件中使用模块userDataImport导入数据,该文件包含以下内容:

import json
from sqlalchemy import create_engine
import sqlalchemy

def userDataImport():
    engine = create_engine('sqlite:///MyProject.db', echo=True)
    conn = engine.connect()
    with open(r'C:\Users\lmills\MyProject\userData.json') as dataFile:
        userData = json.load(dataFile)
            for i in range(len(userData)):
                conn.execute(users.insert(), userid = userData[i]['userid'], altuid = userData[i]['altuid'], lname = userData[i]['lname'], fname = userData[i]['fname'], phoneNum = userData[i]['phoneNum'], emailAddr = userData[i]['emailAddr'])

if __name__ == "__main__": userDataImport()
但是,SQLAlchemy无法识别用户,这是我在CreateTable.py中创建的表,如果我在
元数据之后立即从userDataImport模块中移动代码;在我调用这个模块的情况下,我无法让它工作。

我曾尝试将引擎传递给userDataImport,或者将连接对象传递给userDataImport,但这两种尝试都没有效果(在这两种情况下,引擎=…和conn=…都已删除)。我哪里出错了?

我不确定,但在我看来,您应该从CreateTable导入用户。 比如:

from .CreateTable import users
如果CreateTable和importData文件位于同一目录中,或其他路径,如.CreateTable导入用户的


有关更多信息,请查看我的simple flask项目:

问题的核心是需要在
importData.py
中定义
用户。
用户
应该是什么?嗯,您在另一个文件(
CreateTable.py
)中有一个定义,所以您可能应该导入它

但是等一下,那不行。为什么?因为在导入
CreateTable
时,您会立即再次尝试导入
importData
,因此最终会得到一个循环引用

你如何解决这个问题?答案是排除表定义:

# db.py
from sqlalchemy import *

engine = create_engine(...)
metadata = MetaData(engine)

users = Table(...)
subscribables = Table(...)
...
然后可以在脚本中导入
db

# CreateTable.py
from db import metadata
from importData import userDataImport

if __name__ == "__main__":
    metadata.drop_all()
    metadata.create_all()
    userDataImport()
importData.py

# importData.py
from db import users

def userDataImport():
    conn.execute(users.insert(), ...)

所以我找到了一个解决这个问题的有趣方法。这个问题确实是一个范围问题。由于在插入操作中我没有
用户的上下文,Python变得混乱起来。因此,我发现了一个更像SQL的方法,它在传递给execute函数的字符串中调用SQL语句。通过这种方式,SQLAlchemy处理SQL的解析,并在将表传递给连接时引用表,连接充当
用户的上下文。解决方案如下所示:

engine = create_engine(r'<path to database')
metadata = MetaData(engine)
metadata.reflect()

with engine.begin() as conn:
    conn.execute("insert into users (userid, altid, lname, fname, phone_num, email_addr) values (<user id>, <alternate id>, <last name>, <first name>, <phone number>, <email address>))

engine=创建引擎(我不认为这是一个很好的解决方案。首先,它不起作用。其次,重点是将导入语句从Create Table语句中抽象出来,而这个解决方案完全忽略了这一点。我希望数据库能够允许我将数据导入到它的表中,而不必引用Create Table脚本。)很简单。这似乎不对。元数据是SQLAlchemy本身中的一个实体,应该作为数据库本身的引用,独立于任何python模块。元数据应该在每个模块中重新实例化,以建立与数据库的连接。请参阅:@LukeMills,这显然是错误的。我不知道在哪里您是从中得到这个想法的;文档中当然没有这样说。在我的阅读中,我认为元数据是一个对象,它包含与数据库表相关的信息,因此与数据库相关联。它不仅仅是您的解决方案所建议的局部变量。@Lukemils我想您有fundamental对Python本身的误解。
元数据在我的示例中不是一个局部变量——它是一个模块级属性;它创建一次,并在整个应用程序中共享,即使您多次导入它。它不像C/C++中的
#include
。是的,我理解这一点。但是,它不应该是一个模块首先是e级属性
engine = create_engine(r'<path to database')
metadata = MetaData(engine)
metadata.reflect()

with engine.begin() as conn:
    conn.execute("insert into users (userid, altid, lname, fname, phone_num, email_addr) values (<user id>, <alternate id>, <last name>, <first name>, <phone number>, <email address>))