【问题标题】:How to filter a SQL query on columns in SQLAlchemy?如何过滤 SQLAlchemy 中列的 SQL 查询?
【发布时间】:2019-12-19 15:38:26
【问题描述】:

我是烧瓶炼金术的新手。我想根据 LOC_CODE 列的值过滤 SQL 查询。我做了db.session.query(schools).filter_by(LOC_CODE='X270').first()。但是编译器返回:

(base) C:\Users\antoi\Documents\Programming\musicaltroupefinder>python hello_world.py
C:\ProgramData\Anaconda3\lib\site-packages\flask_sqlalchemy\__init__.py:835: FSADeprecationWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future.  Set it to True or False to suppress this warning.
  'SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and '
 * Serving Flask app "hello_world" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
the total number of school is  3281
[2019-12-18 11:08:31,831] ERROR in app: Exception on / [GET]
Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\util\_collections.py", line 210, in __getattr__
    return self._data[key]
KeyError: 'LOC_CODE'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\orm\base.py", line 399, in _entity_descriptor
    return getattr(entity, key)
  File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\util\_collections.py", line 212, in __getattr__
    raise AttributeError(key)
AttributeError: LOC_CODE

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\site-packages\flask\app.py", line 2446, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\ProgramData\Anaconda3\lib\site-packages\flask\app.py", line 1951, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\ProgramData\Anaconda3\lib\site-packages\flask\app.py", line 1820, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:\ProgramData\Anaconda3\lib\site-packages\flask\_compat.py", line 39, in reraise
    raise value
  File "C:\ProgramData\Anaconda3\lib\site-packages\flask\app.py", line 1949, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\ProgramData\Anaconda3\lib\site-packages\flask\app.py", line 1935, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "hello_world.py", line 37, in index
    school = db.session.query(schools).filter_by(LOC_CODE='X270').first()
  File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\orm\query.py", line 1800, in filter_by
    for key, value in kwargs.items()
  File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\orm\query.py", line 1800, in <listcomp>
    for key, value in kwargs.items()
  File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\orm\base.py", line 402, in _entity_descriptor
    "Entity '%s' has no property '%s'" % (description, key)
sqlalchemy.exc.InvalidRequestError: Entity 'schools' has no property 'LOC_CODE'
127.0.0.1 - - [18/Dec/2019 11:08:31] "[1m[35mGET / HTTP/1.1[0m" 500 -

但是,我在数据库中有这一列:

sqlite> SELECT * FROM SCHOOLS ORDER BY ROWID ASC LIMIT 1
   ...>
   ...> ;
0,,O,0,OAQK,"Victory Schools, DBA The Charter School of Excelle",Elementary,2,0,0,260 WARBURTON AVE,NY,10701,,,,"0K,01,02,03,04",YONKERS,260 WARBURTON AVE,1006,YONKERS,"-73.897156,40.94465",119,"260 WARBURTON AVE, YONKERS, NY, 10701",0,Exact,Match,40.94465,-73.897156,"260 WARBURTON AVE, YONKERS, NY, 10701",R,NY,36,139742928,402,10701
sqlite> PRAGMA table_info(schools);
0|,ATS_CODE,BORO,BORONUM,LOC_CODE,SCHOOLNAME,SCH_TYPE,MANAGED_BY,GEO_DISTRI,ADMIN_DIST,ADDRESS,STATE_CODE,ZIP,PRINCIPAL,PRIN_PH,FAX,GRADES,City,address2,block,city2,coordinates,county_fips,geocoded_address,id,is_exact,is_match,latitude,longitude,returned_address,side,state,state_fips,tiger_line,tract,zipcode|TEXT|0||0

这是我的完整代码:

from flask import Flask  # pip install flask
from flask import render_template
from flask_sqlalchemy import SQLAlchemy


from sqlalchemy import create_engine, MetaData, Table
from sqlalchemy.orm import mapper, sessionmaker    

from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydb.db'
db = SQLAlchemy(app)

schools = db.Table("schools",db.metadata, autoload = True, autoload_with = db.engine)  


@app.route("/")
def index():
    results = db.session.query(schools).count()
    print("the total number of school is ", db.session.query(schools).count())
    school = db.session.query(schools).filter_by(LOC_CODE='X270').first()
    print("School's name is", school.SCHOOLNAME)
    return render_template("index.html")

@app.route("/map")
def shoelaces():
    return "This works now!"

@app.route("/about")
def about():
    return "All about my website"

if __name__ == "__main__":
    app.run()

但是我不能告诉 SQLAlchemy 我们很懒,他应该自己学习数据库,我们使用这行:

我基于this tutorialI couldn't tell SQLAlchemy that he was lazy 并且他应该通过db.Model.metadata.reflect(db.engine) 行自己了解数据库。

有类

我也尝试过上课:

(base) C:\Users\antoi\Documents\Programming\musicaltroupefinder>python hello_world.py
C:\ProgramData\Anaconda3\lib\site-packages\flask_sqlalchemy\__init__.py:835: FSADeprecationWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future.  Set it to True or False to suppress this warning.
  'SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and '
 * Serving Flask app "hello_world" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
[2019-12-20 13:03:58,460] ERROR in app: Exception on / [GET]
Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 1249, in _execute_context
    cursor, statement, parameters, context
  File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\engine\default.py", line 580, in do_execute
    cursor.execute(statement, parameters)
sqlite3.OperationalError: no such column: schools.LOC_CODE

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\site-packages\flask\app.py", line 2446, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\ProgramData\Anaconda3\lib\site-packages\flask\app.py", line 1951, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\ProgramData\Anaconda3\lib\site-packages\flask\app.py", line 1820, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:\ProgramData\Anaconda3\lib\site-packages\flask\_compat.py", line 39, in reraise
    raise value
  File "C:\ProgramData\Anaconda3\lib\site-packages\flask\app.py", line 1949, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\ProgramData\Anaconda3\lib\site-packages\flask\app.py", line 1935, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "hello_world.py", line 32, in index
    school = School.query.filter(School.LOC_CODE == 'X270').all()
  File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\orm\query.py", line 3186, in all
    return list(self)
  File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\orm\query.py", line 3342, in __iter__
    return self._execute_and_instances(context)
  File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\orm\query.py", line 3367, in _execute_and_instances
    result = conn.execute(querycontext.statement, self._params)
  File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 988, in execute
    return meth(self, multiparams, params)
  File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\sql\elements.py", line 287, in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
  File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 1107, in _execute_clauseelement
    distilled_params,
  File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 1253, in _execute_context
    e, statement, parameters, cursor, context
  File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 1473, in _handle_dbapi_exception
    util.raise_from_cause(sqlalchemy_exception, exc_info)
  File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\util\compat.py", line 398, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb, cause=cause)
  File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\util\compat.py", line 152, in reraise
    raise value.with_traceback(tb)
  File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 1249, in _execute_context
    cursor, statement, parameters, context
  File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\engine\default.py", line 580, in do_execute
    cursor.execute(statement, parameters)
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such column: schools.LOC_CODE
[SQL: SELECT schools."LOC_CODE" AS "schools_LOC_CODE"
FROM schools
WHERE schools."LOC_CODE" = ?]
[parameters: ('X270',)]
(Background on this error at: http://sqlalche.me/e/e3q8)
127.0.0.1 - - [20/Dec/2019 13:03:58] "[1m[35mGET / HTTP/1.1[0m" 500 -

这里是代码

from flask import Flask  # pip install flask
from flask import render_template
from flask_sqlalchemy import SQLAlchemy

from sqlalchemy import create_engine, MetaData, Table
from sqlalchemy.orm import mapper, sessionmaker


from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydb.db'
db = SQLAlchemy(app)

class School(db.Model):
    __tablename__ = 'schools'
    # __table_args__ = { 'extend_existing': True }
    LOC_CODE = db.Column(db.Text, primary_key=True)   


@app.route("/")
def index():
    school = School.query.filter(School.LOC_CODE == 'X270').first()
    print("School's name is", school.SCHOOLNAME)
    return render_template("index.html")

【问题讨论】:

  • 在您的第二次尝试中,您将通过类创建一个 schools 表和一个 School 表。尝试使用类的 tablename 参数组合它们。
  • @Attack68 当然,它确实改变了错误消息

标签: python python-3.x sqlite sqlalchemy flask-sqlalchemy


【解决方案1】:

该错误与您使用dbsession 的方式有关。在您的第三个代码 sn-p 中,配置由 School 类处理,您的散列线对于通过它进行的后续查询很重要。在db.engine 配置上使用reflect 方法也很重要。将filter() 切换为filter_by() 也会产生结果。我将.py 文件分成两份,一份用于创建sqlite 数据库,另一份用于Flask 会话。在两个脚本的结尾行都进行了测试,只需进行最小的更改即可获得没有错误和预期的结果。

#create_db.py

from sqlalchemy import create_engine, MetaData, Table, Column, String
from sqlalchemy.orm import mapper, sessionmaker

engine= create_engine('sqlite:///example.db')
metadata = MetaData(engine)


table = Table('schools', metadata,
            Column('name', String),
            Column('LOC_CODE', String))

metadata.create_all()
ins = table.insert().values(name = 'Victory',
                            LOC_CODE = 'X270'
                            )

conn = engine.connect()
conn.execute(ins)

Session = sessionmaker(bind=engine)
session = Session()

schools = table


# Test session below
results = session.query(schools).count()
filt = session.query(schools).filter_by(LOC_CODE='X270').first()


print(results)
print(filt)
#filter_by_test.py

from flask import Flask
from flask import render_template
from flask_sqlalchemy import SQLAlchemy

from sqlalchemy import create_engine, MetaData, Table, Column, String



app = Flask(__name__)

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///example.db'

db = SQLAlchemy(app)

db.Model.metadata.reflect(db.engine)

class School(db.Model):
    __tablename__ = 'schools'
    __table_args__ = {'extend_existing': True}
    LOC_CODE = db.Column(db.Text, primary_key = True)


@app.route("/")
def hello():
    print("Total number of schools is", School.query.count())

    school = School.query.filter_by(LOC_CODE='X270').first()
    print(school.name)

hello()
#combined.py

from flask import Flask
from flask import render_template
from flask_sqlalchemy import SQLAlchemy

from sqlalchemy import create_engine, MetaData, Table, Column, String

import sqlite3
import pandas as pd

#data = 'schools-geocoded - schools-geocoded.csv'
#df = pd.read_csv(data)
#con = sqlite3.connect('example2.db')

#df.to_sql("schools", con)


app = Flask(__name__)

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///example2.db'

db = SQLAlchemy(app)

db.Model.metadata.reflect(db.engine)

class School(db.Model):
    __tablename__ = 'schools'
    __table_args__ = {'extend_existing': True}
    LOC_CODE = db.Column(db.Text, primary_key = True)


@app.route("/")
def hello():
    print("Total number of schools is", School.query.count())

    school = School.query.filter_by(LOC_CODE='X270').first()
    print(school.SCHOOLNAME)

hello()

【讨论】:

  • 感谢您的回答我仍然无法将它应用到我的数据库文件中,您可以找到 here。我不认为它编码错误the csv file
  • 我用第三个脚本 combined.py 更新了答案。从 csv 中删除用于创建 db 的哈希线。它产生了预期的结果。
  • 谢谢,在这种情况下,csv 文件中的两列会产生一些问题,因为它们与另外两列重复。我怎样才能跳过它们? (是cityaddress
  • df.to_sql 行之前,您可以删除列。 df.drop(columns=['address2', 'city2'])df.drop(['address2', 'city2'], axis=1).
【解决方案2】:

通过首先从 python 控制台运行这些命令,然后启动烧瓶应用程序,我能够克服您的第一个错误。这将创建您的代码在给定示例中使用的数据库。如果您有一个现有的数据库,则需要将 URI 更改为它所在的位置。您正在使用的 URI 将使用此命令创建。如果需要,我会查看 Flask-SQLAlchemy 文档以了解如何连接到现有数据库。

from yourapplication import db
db.create_all()

来源: https://flask-sqlalchemy.palletsprojects.com/en/2.x/quickstart/

【讨论】:

  • 我有一个现有的数据库。它与脚本位于同一文件夹中。但是,即使指定 mydb.db 的完整路径,我仍然会收到相同的错误。
  • @IggyPass 您的数据库文件有问题。我尝试了几种创建数据库的方法,包括教程包含的方式,它们都可以工作。我会通过教程并尝试使用 TablePlus 进行创建
  • 好的,我来了。然而,即使没有在 TablePlus 上导入重复项,我也无法使用 my csv file 再次创建我的表
  • @IggyPass 您当前的错误是什么?您是否也将所有内容都更改为文本?我在我的代码中排除了使用反射方法
  • 在 TablePlus 上? create table failed
猜你喜欢
  • 2015-02-02
  • 1970-01-01
  • 2015-01-15
  • 1970-01-01
  • 2015-05-11
  • 2018-08-09
  • 2011-10-16
  • 2021-08-10
  • 1970-01-01
相关资源
最近更新 更多