尝试使用SQLAlchemy表达式语言将用户数据从JSON文件导入数据库时,出现错误:
Sub updatedbtest2()
Dim cn As ADODB.Connection, rs As ADODB.Recordset
Dim rng As Range
Dim lngRow As Long
Dim sQID, LR
Dim sSQL As String
LR = Range("A" & Rows.Count).End(xlUp).Row
'Debug.Print LR
'Upd = LR - 1
lngRow = 2
Set cn = New ADODB.Connection
cn.Open "Provider = Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=C:\Database\sales.accdb;"
Do While lngRow <= LR
sQID = Cells(lngRow, 61).Value
Set rs = New ADODB.Recordset
sSQL = "SELECT * FROM PandR WHERE QID ='" & sQID & "';"
With rs
.Open Source:=sSQL, ActiveConnection:=cn, LockType:=adLockOptimistic
.Fields("QorB") = Cells(lngRow, 60).Value
.Fields("BDate") = Cells(lngRow, 62).Value
.Update
End With
'Next rng
lngRow = lngRow + 1
rs.Close
Set rs = Nothing
Loop
cn.Close
Set cn = Nothing
End Sub
回溯如下:
NameError: name 'users' is not defined
我在Python程序CreateTable.py:
中发出create table语句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导入数据,该文件包含以下内容:
from sqlalchemy import create_engine, Table, Column, Integer, String,
MetaData, ForeignKey
import importData
import json
engine = create_engine('sqlite:///MyProject.db', echo=True)
metadata = MetaData(engine)
metadata.drop_all(engine)
users = Table('users', metadata,
Column('userid', Integer, primary_key=True),
Column('altuid', String(12)),
Column('lname', String(32)),
Column('fname', String(32)),
Column('phone_num', Integer, nullable=False),
Column('email_addr', String(32), nullable=False),
)
subscribables = Table('subscribables', metadata,
Column('subtag', Integer, primary_key=True),
Column('message_template', String(64)),
Column('descriptor_string', String(64)),
)
user_subs = Table('user_subs', metadata,
Column('userid', Integer, ForeignKey('users.userid')),
Column('subtag', Integer, ForeignKey('subscribables.subtag')),
)
user_prefs = Table('user_prefs', metadata,
Column('userid', Integer, ForeignKey('users.userid')),
Column('type_id', String(8), ForeignKey('notification_type.type_id')),
)
notification_type = Table('notification_type', metadata,
Column('type_id', String(8), primary_key=True),
Column('typename', String(8), nullable=False),
Column('Template', String(64)),
)
metadata.create_all()
importData.userDataImport()
然而SQLAlchemy无法识别用户,这是我在CreateTable.py中创建的表。如果我在CreateTable.py中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()
之后立即从userDataImport模块移动代码,一切正常,花花公子;在我称这个模块无法让它工作的情况下。
我试图将引擎传递给userDataImport,并将连接对象传递给userDataImport,但这两种尝试都没有成效(在两种情况下引擎= ...和conn = ...删除)。我哪里错了?
答案 0 :(得分:1)
所以我找到了解决这个问题的有趣方法。这个问题确实是一个范围问题。鉴于我在插入操作中没有users
的上下文这一事实,Python变得困惑。所以我发现了一个更像SQL的方法,它调用传递给execute函数的字符串中的SQL语句。这样,SQLAlchemy处理了SQL的解析,并引用了表,因为它被传递给连接,该连接充当users
的上下文。解决方案如下所示:
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>))
以小于号和大于号的方式包含的实体是特定值。
这成功地以原始问题中发布的方法将数据插入到数据库中。同样,更新/选择也可以使用这种类似SQL的方法,而标准users.update(...)
users.select(...)
则没有。
对于后代,这里是SQLAlchemy文档页面,其中包含类似SQL的插入的特定语法:http://docs.sqlalchemy.org/en/rel_1_0/core/tutorial.html#using-textual-sql
答案 1 :(得分:0)
我不确定,但在我看来,您应该从CreateTable导入用户。 类似的东西:
from .CreateTable import users
如果CreateTable和importData文件位于同一目录或其他路径中,如from <some-directory>.CreateTable import users
有关详细信息,您可以查看我的简单烧瓶项目:bitbucket-repository
答案 2 :(得分:0)
问题的核心是您需要在users
中定义importData.py
。什么是users
应该是什么?好吧,你有一个不同文件(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(), ...)