Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在SQLAlchemy中使用筛选器进行选择时出现奇怪的SQL错误_Python_Sqlalchemy - Fatal编程技术网

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.'