Python 在SQLAlchemy中使用筛选器进行选择时出现奇怪的SQL错误
编辑我找到了答案,它与模型的设置方式无关。我试图将Python 在SQLAlchemy中使用筛选器进行选择时出现奇怪的SQL错误,python,sqlalchemy,Python,Sqlalchemy,编辑我找到了答案,它与模型的设置方式无关。我试图将request.form从flask传递到实际创建地址的函数。显然,将其转换为kwargs会产生问题。手动指定每个参数可以使一切正常工作 我是SQLAlchemy的新手,到目前为止一切都很顺利,但我遇到了一个问题,我完全被难住了,所以我希望这里的人知道我做错了什么 我有一个地址模型,我正试图从中进行选择。模型如下所示: class Address(Base): __tablename__ = 'address' id = Col
request.form
从flask传递到实际创建地址的函数。显然,将其转换为kwargs
会产生问题。手动指定每个参数可以使一切正常工作
我是SQLAlchemy的新手,到目前为止一切都很顺利,但我遇到了一个问题,我完全被难住了,所以我希望这里的人知道我做错了什么
我有一个地址模型,我正试图从中进行选择。模型如下所示:
class Address(Base):
__tablename__ = 'address'
id = Column(Integer, primary_key=True)
comment = Column(String(255))
address1 = Column(String(100))
address2 = Column(String(100))
city = Column(String(45))
state = Column(String(2))
zip = Column(String(5))
zip4 = Column(String(4))
lat = Column(Float)
lon = Column(Float)
我正在尝试匹配通过我的应用程序输入的地址元素,以查看是否可以在不使用地理编码的情况下找到纬度和经度。我在其他有效的查询中使用了filter\u by
,因此我在这里尝试同样的方法:(address
dict来自我的应用程序的post参数)
不幸的是,此操作失败,出现SQL错误:
ProgrammingError: (ProgrammingError) (1064, 'You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for the right
syntax to use near \') AND address.state = ("\'XX\'",) AND address.zip =
("\'XXXXX\'",) AND address.city \' at line 3')
这看起来很难看!额外的()
从哪里来?我在调用create_engine()
时打开了echo=True
,它打印了一个似乎正确的查询(我在mysql客户机中尝试过,没有问题):
但是它所说的输出参数似乎有点奇怪,尽管我不确定这是否只是python对象,或者它是否真的将以这种方式传输到MySQL:(注意,X字符只是我真实地址的替换)
只是为了好玩,我尝试使用filter()
而不是filter\u by()
但是我得到了同样的错误:
matched_address = database.session.query(Address).filter(
and_(Address.address1==address['address1'], Address.city==address['city'],
Address.state==address['state'],Address.zip==address['zip'])).one()
抱歉,如果这是一个基本问题。提前感谢您的帮助 您是否尝试打印出
地址['address1']
等的值?repr
可能是最清晰的
[编辑]
查看文档后,我想知道您是否应该这样做:
from sqlalchemy import and_
filter(and_(address1 == address['address1'], city == address['city'], ...))
您的类定义对我来说很有用,对您没有提供的大量设置代码进行了模块化。为下面的代码量道歉。第一,定义:
from sqlalchemy import create_engine, Column, Integer, String, Float
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Address(Base):
__tablename__ = 'address'
id = Column(Integer, primary_key=True)
comment = Column(String(255))
address1 = Column(String(100))
address2 = Column(String(100))
city = Column(String(45))
state = Column(String(2))
zip = Column(String(5))
zip4 = Column(String(4))
lat = Column(Float)
lon = Column(Float)
#note I am only initializing the querying columns. i am lazy
def __init__(self, cm, a1, ct, st):
self.comment = cm
self.address1 = a1
self.city = ct
self.state = st
将该类定义放入文件MyAddr.py并导入,然后启动python。注意,我在SA演示中使用sqlite
>>> from sqlalchemy import create_engine
>>> engine = create_engine('sqlite:///:memory:', echo=False)
>>> from sqlalchemy.orm import sessionmaker
>>> Session = sessionmaker(bind=engine)
>>> from MyAddr import Base, Address
>>> Base.metadata.create_all(engine)
>>>
>>> a = '1234 Main St.'
>>> c = 'Anywhere'
>>> st= 'MO'
>>> cm= 'Blah blah blah blah blah'
>>>
>>> addr = Address(cm, a, c, st)
>>>
>>> s = Session()
>>> s.add(addr)
>>> s.commit()
>>>
>>> q = s.query(Address).filter_by(address1=a,city=c)
>>>
>>> q.one()
<op.Address object at 0x10d158a50>
>>> q = s.query(Address).filter_by(address1=a,city=c,state=st)
>>> q.one()
<op.Address object at 0x10d158a50>
>>> abc = q.one()
>>> abc
<op.Address object at 0x10d158a50>
>>> abc.city
u'Anywhere'
>>> abc.state
u'MO'
>>> abc.address1
u'1234 Main St.'
来自sqlalchemy导入创建引擎的>>
>>>engine=create_engine('sqlite://:memory:',echo=False)
>>>从sqlalchemy.orm导入sessionmaker
>>>会话=会话生成器(绑定=引擎)
>>>从MyAddr导入基,地址
>>>Base.metadata.create_all(引擎)
>>>
>>>a=‘主大街1234号’
>>>c=‘任何地方’
>>>st=‘MO’
>>>cm=‘废话废话废话’
>>>
>>>地址=地址(cm、a、c、st)
>>>
>>>s=会话()
>>>s.add(地址)
>>>美国提交
>>>
>>>q=s.query(Address)。筛选依据(address1=a,city=c)
>>>
>>>问题1()
>>>q=s.query(Address).筛选依据(address1=a,city=c,state=st)
>>>问题1()
>>>abc=q.one()
>>>abc
>>>abc城市
你在哪里
>>>abc州
乌莫
>>>abc.address1
u'1234 Main St.'
由于您的类定义可以起作用,您的问题中没有足够的信息(对我来说)来了解它为什么不起作用。也许是因为你的输入数据?错误消息包含两组引号,一组已转义。您的输入dict是否包含带引号的字符串?我找到了答案,它与模型的设置方式无关。我试图将request.form从flask传递给一个实际创建地址的函数。显然,将其转换为kwargs会引起问题。手动指定每个参数可以使一切正常工作。是Python中的内置函数。将其用作变量名会使您难以追踪此类错误。@DavidNehme我尝试仅使用城市或州来查看查询是否有效,但仍然遇到相同的问题。是的,我打印出了值,它们是正确的。我用的是烧瓶。地址信息是从表单输入捕获的。不确定。我原以为
filter
必须按照我最初的问题中的方式来调用(使用整个类定义,并使用=
而不是单个定义),我已经仔细检查了一遍,您的回答是正确的,它应该使用=
(上面已更正)。您的设置看起来与我的类似。我正在使用mysql。主要区别在于我没有为类创建自定义init。据我所知,这里提供了一个基本类,可以满足我的需要。如果有人想知道为什么会发生这种情况,我遇到了同样的情况,可以提供一些额外的细节:Flask使用Werkzeug的ImmutableMultiDict类来处理它的请求参数。由于IMD类在尝试直接解包该类中的请求参数时需要为给定的键存储多个值(以处理HTML提交),因此每个值都被包装在一个列表中。因此,这些值(都是列表包装的)被传递给SQLAlchemy,它当然需要字符串,并且在传递列表时失败得很惨。轻松修复:解包前使用to_dict()方法。
from sqlalchemy import and_
filter(and_(address1 == address['address1'], city == address['city'], ...))
from sqlalchemy import create_engine, Column, Integer, String, Float
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Address(Base):
__tablename__ = 'address'
id = Column(Integer, primary_key=True)
comment = Column(String(255))
address1 = Column(String(100))
address2 = Column(String(100))
city = Column(String(45))
state = Column(String(2))
zip = Column(String(5))
zip4 = Column(String(4))
lat = Column(Float)
lon = Column(Float)
#note I am only initializing the querying columns. i am lazy
def __init__(self, cm, a1, ct, st):
self.comment = cm
self.address1 = a1
self.city = ct
self.state = st
>>> from sqlalchemy import create_engine
>>> engine = create_engine('sqlite:///:memory:', echo=False)
>>> from sqlalchemy.orm import sessionmaker
>>> Session = sessionmaker(bind=engine)
>>> from MyAddr import Base, Address
>>> Base.metadata.create_all(engine)
>>>
>>> a = '1234 Main St.'
>>> c = 'Anywhere'
>>> st= 'MO'
>>> cm= 'Blah blah blah blah blah'
>>>
>>> addr = Address(cm, a, c, st)
>>>
>>> s = Session()
>>> s.add(addr)
>>> s.commit()
>>>
>>> q = s.query(Address).filter_by(address1=a,city=c)
>>>
>>> q.one()
<op.Address object at 0x10d158a50>
>>> q = s.query(Address).filter_by(address1=a,city=c,state=st)
>>> q.one()
<op.Address object at 0x10d158a50>
>>> abc = q.one()
>>> abc
<op.Address object at 0x10d158a50>
>>> abc.city
u'Anywhere'
>>> abc.state
u'MO'
>>> abc.address1
u'1234 Main St.'