对于想了解在SQLAlchemy中查询属性列表而不是元组的读者,本文将提供新的信息,我们将详细介绍sqlalchemy查询指定字段,并且为您提供关于python–在SQLAlchemy中,如何查询复合
对于想了解在SQLAlchemy中查询属性列表而不是元组的读者,本文将提供新的信息,我们将详细介绍sqlalchemy查询指定字段,并且为您提供关于python – 在SQLAlchemy中,如何查询复合主键?、SqlAlchemy:筛选以匹配所有而不是列表中的任何值?、为什么查询在SQLAlchemy中调用自动刷新?、删除未在sqlalchemy中级联到表的有价值信息。
本文目录一览:- 在SQLAlchemy中查询属性列表而不是元组(sqlalchemy查询指定字段)
- python – 在SQLAlchemy中,如何查询复合主键?
- SqlAlchemy:筛选以匹配所有而不是列表中的任何值?
- 为什么查询在SQLAlchemy中调用自动刷新?
- 删除未在sqlalchemy中级联到表
在SQLAlchemy中查询属性列表而不是元组(sqlalchemy查询指定字段)
我正在查询模型的ID,并获得一个(int,)
元组列表,而不是ID列表。有没有一种直接查询属性的方法?
result = session.query(MyModel.id).all()
我知道有可能做
results = [r for (r,) in results]
查询是否可以直接返回该表单,而不必自己处理呢?
python – 在SQLAlchemy中,如何查询复合主键?
我正在使用sqlAlchemy以编程方式查询具有复合外键的表.例如.:
CREATE TABLE example (
id INT NOT NULL,date TIMESTAMP NOT NULL,data VARCHAR(128)
PRIMARY KEY (id,date)
)
我想拿一个值列表并获取行例如:
interesting_data = (
(1,'2016-5-1'),(1,'2016-6-1'),(2,(3,)
select(
[example.c.id,example.c.date,example.c.data],).where(example.primary_key.in_(interesting_data)
如果每列都是独立的,我可以做到
interesting_ids = [1,2,3]
interesting_dates = ['2016-5-1','2016-6-1']
select(
[example.c.id,).where(
example.c.id.in_(interesting_ids)
).where(
example.c.date.in_(interesting_dates)
)
但这显然无法仅带来唯一匹配(id,date)元组.我怀疑有一种方法可以指定要查询的复合主键,但搜索后找不到任何文档.
from sqlalchemy import and_,or_,select
stmt = select(
[example.c.id,example.c.data]
).where(or_(and_(example.c.id==data[0],example.c.date==data[1])
for data in interesting_data))
但是,我注意到的另一个问题是您将日期列与字符串数据类型进行比较. interesting_data列表应该是
import datetime as dt
interesting_data = (
(1,dt.date(2016,5,1)),6,)
另请注意,可以创建基本语句,然后逐步向其添加子句,从而导致(希望)更好的易读性和代码重用.
因此,可以将上面的内容写成
base_stmt = select([example.c.id,example.c.data])
wheres = or_(and_(example.c.id==data[0],example.c.date==data[1])
for data in interesting_data))
stmt = base_stmt.where(wheres)
这会生成以下sql(由我添加的新行和空格):
SELECT example.id,example.date,example.data
FROM example
WHERE
example.id = :id_1 AND example.date = :date_1
OR example.id = :id_2 AND example.date = :date_2
OR example.id = :id_3 AND example.date = :date_3
OR example.id = :id_4 AND example.date = :date_4
OR example.id = :id_5 AND example.date = :date_5
注意:如果要像这样过滤很多行,那么创建临时表,从interesting_data向此临时表插入行,然后将内部连接插入此表可能更有效,而不是如图所示添加where子句以上.
SqlAlchemy:筛选以匹配所有而不是列表中的任何值?
我想查询一个结表列的值aID
匹配ID列表的所有值ids=[3,5]
列bID
。
这是我的联结表(JT
):
aID bID
1 1
1 2
2 5
2 3
1 3
3 5
我有这个查询: session.query(JT.aID).filter(JT.bID.in_(ids)).all()
该查询返回的aID
值1
,2
并且3
因为它们都与行的任一3
或5
在bID
列。我希望查询返回的内容是2
因为这是唯一在其列aID
中具有ids
列表所有值的值bID
。
不知道如何更好地解释问题,但是我如何得出结果呢?
为什么查询在SQLAlchemy中调用自动刷新?
您在上面看到的代码只是一个示例,但是可以重现此错误:
sqlalchemy.exc.IntegrityError: (raised as a result of Query-invoked autoflush; consider using a session.no_autoflush block if this flush is occurring prematurely)(sqlite3.IntegrityError) NOT NULL constraint failed: X.nn [SQL: ''INSERT INTO "X" (nn, val) VALUES (?, ?)''] [parameters: (None, 1)]
映射的实例仍添加到会话中。该实例想知道(这意味着在数据库上查询)是否存在其他自己实例类型具有相同值的实例。还有第二个属性/列(_nn
)。它指定为NOTNULL
。但默认情况下为NULL
。
当实例(如示例中)仍添加到会话中时,将query.one()
调用一个调用以自动刷新。刷新创建一个INSERT
尝试存储实例的。之所以失败,_nn
是因为它仍然为null并违反了NOTNULL
约束。
这就是我目前所了解的。但是问题是为什么它要调用自动冲洗?我可以阻止吗?
#!/usr/bin/env python3import os.pathimport osimport sqlalchemy as sa import sqlalchemy.orm as saoimport sqlalchemy.ext.declarative as sadfrom sqlalchemy_utils import create_database_Base = sad.declarative_base()session = Noneclass X(_Base): __tablename__ = ''X'' _oid = sa.Column(''oid'', sa.Integer, primary_key=True) _nn = sa.Column(''nn'', sa.Integer, nullable=False) # NOT NULL! _val = sa.Column(''val'', sa.Integer) def __init__(self, val): self._val = val def test(self, session): q = session.query(X).filter(X._val == self._val) x = q.one() print(''x={}''.format(x))dbfile = ''x.db''def _create_database(): if os.path.exists(dbfile): os.remove(dbfile) engine = sa.create_engine(''sqlite:///{}''.format(dbfile), echo=True) create_database(engine.url) _Base.metadata.create_all(engine) return sao.sessionmaker(bind=engine)()if __name__ == ''__main__'': session = _create_database() for val in range(3): x = X(val) x._nn = 0 session.add(x) session.commit() x = X(1) session.add(x) x.test(session)
当然,解决方案是在调用之前 不
将实例添加到会话query.one()
中。这项工作。但是在我的实际(但是对于这个问题来说很复杂)的用例中,这不是一个很好的解决方案。
答案1
小编典典如何关闭自动冲洗功能:
临时的:您可以在查询数据库的代码段中使用no_autoflush上下文管理器,即在
X.test
方法中:def test(self, session):with session.no_autoflush: q = session.query(X).filter(X._val == self._val) x = q.one() print(''x={}''.format(x))
autoflush=False
全会期:只需传递给您的会议主持人即可:return sao.sessionmaker(bind=engine, autoflush=False)()
删除未在sqlalchemy中级联到表
我正在开发使用sqlalchemy 0.6的现有应用程序的扩展。
该应用程序具有以非声明方式创建的sqlalchemy表。我正在尝试在扩展程序中创建一个新表,该表的外键列指向应用程序数据库中主表的主键,并且以声明方式创建它。
这一切都很好,加载扩展程序后就创建了表,一点也没有抱怨。我的表将打印出来,并演示已经添加了新行。我想要并认为可能的(但不知道,因为我从未使用过sql或任何其他数据库)是在删除应用程序主表中具有相应外键的行时删除表中的相应行。
到目前为止,已经尝试了许多排列,但没有任何效果。我认为设置了backref并定义了具有级联的delete的关系,应该不会有问题。因为新表是在扩展名中定义的,扩展名应该只是插件,所以我根本不想编辑主应用程序中的代码,至少这是我的目标。但是,我遇到的问题之一是我要引用的主应用程序表,在其类中没有定义成员变量,未在其映射器中声明其主键并且仅在表中声明了主键。
。这使得很难创建一个Relation(ship)子句,该子句的第一个自变量必须是类或映射器(在这种情况下,都没有声明主键)。有什么办法可以做到这一点?
ps-这是我正在使用的一些代码。LocalFile是声明性类。所有连接细节均由主应用程序处理。
if not self.LocalFile.__table__.exists(bind=Engine): self.LocalFile__table__.create(bind=Engine)
这是LocalFile类-基类是声明性基类,在构造函数中传递了bind = Engine:
class LocalFile(Base): __tablename__ = ''local_file'' _id = Column(Integer, Sequence(''local_file_sequence'', start=1, increment=1), primary_key=True) _filename = Column(String(50), nullable=False) _filepath = Column(String(128), nullable=False) _movieid = Column(Integer, ForeignKey(db.tables.movies.c.movie_id, onupdate=''CASCADE'', ondelete=''CASCADE'')) #movies = relation(db.Movie, backref="local_file", cascade="all") @property def filename(self): return self._filename @filename.setter def filename(self, filename): self._filename = filename @property def filepath(self): return self._filepath @filepath.setter def filepath(self, filepath): self._filepath = filepath @property def movieid(self): return self._movieid @movieid.setter def movieid(self, movieid): self._movieid = movieid @property def id(self): return self._id @id.setter def id(self, id): self._id = id filename = synonym(''_filename'', descriptor=filename) movieid = synonym(''_movieid'', descriptor=movieid) filepath = synonym(''_filepath'', descriptor=filepath) id = synonym(''_id'', descriptor=id) def __init__(self, filename, filepath, movieid): self._filename = filename self._filepath = filepath self._movieid = movieid def __repr__(self): return "<User(''%s'',''%s'', ''%s'')>" % (self.filename, self.filepath, self.movieid)
编辑:
后端是sqlite3。下面是使用echo命令生成的表的创建代码(感谢您指出这一点,它非常有用-
我已经怀疑现有应用程序生成的SQL远远超出了必要)。报告的sql表创建之后是删除行时生成的代码。我个人看不到任何引用本地文件表中可能删除行的语句,但是我目前几乎不了解sql。谢谢。
2011-12-29 16:29:18,530 INFO sqlalchemy.engine.base.Engine.0x...0650 CREATE TABLE local_file (_id INTEGER NOT NULL, _filename VARCHAR(50) NOT NULL, _filepath VARCHAR(128) NOT NULL, _movieid INTEGER, PRIMARY KEY (_id), FOREIGN KEY(_movieid) REFERENCES movies (movie_id) ON DELETE CASCADE ON UPDATE CASCADE
)
2011-12-29T16:29:18: I: sqlalchemy.engine.base.Engine.0x...0650(base:1387): CREATE TABLE local_file (_id INTEGER NOT NULL, _filename VARCHAR(50) NOT NULL, _filepath VARCHAR(128) NOT NULL, _movieid INTEGER, PRIMARY KEY (_id), FOREIGN KEY(_movieid) REFERENCES movies (movie_id) ON DELETE CASCADE ON UPDATE CASCADE
)
2011-12-29 16:29:18,534 INFO sqlalchemy.engine.base.Engine.0x...0650 ()2011-12-29T16:29:18: I: sqlalchemy.engine.base.Engine.0x...0650(base:1388): ()2011-12-29 16:29:18,643 INFO sqlalchemy.engine.base.Engine.0x...0650 COMMIT2011-12-29T16:29:18: I: sqlalchemy.engine.base.Engine.0x...0650(base:1095): COMMIT
表中的行会为两个表生成以下内容:
本地文件表:(,u‘310 To Yuma’)(,u’Ravenous’)
现有应用中的电影表:(,u’IMDb-3:10 to Yuma’)(,u’Ravenous’)
删除行时的代码太长,以至于我无法在此处包括它(大约200行-删除一行不是太多吗?),但是它没有引用删除localfile表中的行。有如下语句:
2011-12-29 17:09:17,141 INFO sqlalchemy.engine.base.Engine.0x...0650 UPDATE movies SET poster_md5=?, updated=? WHERE movies.movie_id = ? 2011-12-29T17:09:17: I: sqlalchemy.engine.base.Engine.0x...0650(base:1387): UPDATE movies SET poster_md5=?, updated=? WHERE movies.movie_id = ? 2011-12-29 17:09:17,142 INFO sqlalchemy.engine.base.Engine.0x...0650 (None, ''2011-12-29 17:09:17.141019'', 2) 2011-12-29T17:09:17: I: sqlalchemy.engine.base.Engine.0x...0650(base:1388): (None, ''2011-12-29 17:09:17.141019'', 2) 2011-12-29 17:09:17,150 INFO sqlalchemy.engine.base.Engine.0x...0650 DELETE FROM posters WHERE posters.md5sum = ? 2011-12-29T17:09:17: I: sqlalchemy.engine.base.Engine.0x...0650(base:1387): DELETE FROM posters WHERE posters.md5sum = ? 2011-12-29 17:09:17,157 INFO sqlalchemy.engine.base.Engine.0x...0650 (u''083841e14b8bb9ea166ea4b2b976f03d'',)
答案1
小编典典在SQLite中,您必须显式打开对外键的支持,否则它将忽略任何与外键相关的SQL。
engine = create_engine(database_url)def on_connect(conn, record): conn.execute(''pragma foreign_keys=ON'')from sqlalchemy import eventevent.listen(engine, ''connect'', on_connect)
关于在SQLAlchemy中查询属性列表而不是元组和sqlalchemy查询指定字段的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于python – 在SQLAlchemy中,如何查询复合主键?、SqlAlchemy:筛选以匹配所有而不是列表中的任何值?、为什么查询在SQLAlchemy中调用自动刷新?、删除未在sqlalchemy中级联到表的相关知识,请在本站寻找。
本文标签: