我有一个简单的模型类,代表两个角色之间的战斗:
class WaifuPickBattle(db.Model):
"""Table which represents a where one girl is chosen as a waifu."""
__tablename__ = "waifu_battles"
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False)
date = db.Column(db.DateTime, nullable=False)
winner_name = db.Column(db.String, nullable=False)
loser_name = db.Column(db.String, nullable=False)
def get_battle_appearences_cte():
"""Create a sqlalchemy subquery of the battle appearences."""
wins = select([
WaifuPickBattle.date,
WaifuPickBattle.winner_name.label("name"),
expression.literal_column("1").label("was_winner"),
expression.literal_column("0").label("was_loser")
])
losses = select([
WaifuPickBattle.date,
WaifuPickBattle.loser_name.label("name"),
expression.literal_column("0").label("was_winner"),
expression.literal_column("1").label("was_loser")
])
return wins.union_all(losses).cte("battle_appearence")
def query_most_battled_waifus():
"""Find the waifus with the most battles in a given date range."""
appearence_cte = get_battle_appearences_cte()
query = \
select([
appearence_cte.c.name,
func.sum(appearence_cte.c.was_winner).label("wins"),
func.sum(appearence_cte.c.was_loser).label("losses"),
])\
.group_by(appearence_cte.c.name)\
.order_by(func.count().desc())\
.limit(limit)
return db.session.query(query).all()
WITH battle_appearence AS
(
SELECT
waifu_battles.date AS date,
waifu_battles.winner_name AS name,
1 AS was_winner,
0 AS was_loser
FROM waifu_battles
UNION ALL
SELECT
waifu_battles.date AS date,
waifu_battles.loser_name AS name,
0 AS was_winner,
1 AS was_loser
FROM waifu_battles
)
SELECT
name AS name,
wins AS wins,
losses AS losses
FROM
(
SELECT
battle_appearence.name AS name,
sum(battle_appearence.was_winner) AS wins,
sum(battle_appearence.was_winner) AS losses
FROM battle_appearence
GROUP BY battle_appearence.name
ORDER BY count(*) DESC
)
sqlalchemy.exc.ProgrammingError: (psycopg2.errors.SyntaxError) subquery in FROM must have an alias
LINE 6: FROM (SELECT battle_appearence.name AS name, count(battle_ap... ^ HINT: For example, FROM (SELECT ...) [AS] foo.
[SQL: WITH battle_appearence AS (SELECT waifu_battles.date AS date, waifu_battles.winner_name AS name, 1 AS was_winner, 0 AS was_loser FROM waifu_battles UNION ALL SELECT waifu_battles.date AS date, waifu_battles.loser_name AS name, 0 AS was_winner, 1 AS was_loser FROM waifu_battles) SELECT name AS name, wins AS wins, losses AS losses FROM (SELECT battle_appearence.name AS name, count(battle_appearence.was_winner) AS wins, count(battle_appearence.was_winner) AS losses FROM battle_appearence GROUP BY battle_appearence.name ORDER BY count(*) DESC)] (Background on this error at: http://sqlalche.me/e/f405)
<alias>.<column> 来解决此问题。在主选择语句中 - Postgres 需要在子选择上使用别名在别处有详细记录。 .alias("foo")到查询:query = query\
...\
.alias("foo")
WITH battle_appearence AS
(
SELECT
waifu_battles.date AS date,
waifu_battles.winner_name AS name,
1 AS was_winner,
0 AS was_loser
FROM waifu_battles
UNION ALL
SELECT
waifu_battles.date AS date,
waifu_battles.loser_name AS name,
0 AS was_winner,
1 AS was_loser
FROM waifu_battles
)
SELECT
battle_appearence.name,
sum(battle_appearence.was_winner) AS wins,
sum(battle_appearence.was_winner) AS losses
FROM battle_appearence
GROUP BY battle_appearence.name
ORDER BY count(*) DESC
"foo"别名似乎被忽略了,但对生成的查询产生了重大影响。
最佳答案
答案
SQLalchemy decides to introduce it despite not being explicitly instructed to
db.sesion.query(query) 的那一刻使用子查询(虽然你可能不知道)。使用 db.session.execute(query)反而。why did adding the alias prevent the sub-select from being created and why is the alias not used! The "foo" alias was seemingly disregarded yet had a substantial effect on the generated query.
print(query)偷看引擎盖下并了解问题所在 - 这次运气不好,它并没有告诉你全部真相。WITH battle_appearence AS
(
SELECT
waifu_battles.date AS date,
waifu_battles.winner_name AS name,
1 AS was_winner,
0 AS was_loser
FROM waifu_battles
UNION ALL
SELECT
waifu_battles.date AS date,
waifu_battles.loser_name AS name,
0 AS was_winner,
1 AS was_loser
FROM waifu_battles
)
SELECT foo.name AS foo_name, foo.wins AS foo_wins, foo.losses AS foo_losses
FROM (
SELECT
battle_appearence.name AS name,
sum(battle_appearence.was_winner) AS wins,
sum(battle_appearence.was_loser) AS losses
FROM battle_appearence
GROUP BY battle_appearence.name
ORDER BY count(*) DESC
LIMIT ?
)
AS foo
str(query.compile()) 的结果.您可以调整它以使用 postgres 方言:dialect = postgresql.dialect()
str(query.compile(dialect=dialect))
query.compile (简化)与调用 dialect.statement_compiler(dialect, query, bind=None) 相同db.session.query(query).all() 时生成的。 .如果您只输入 str(db.session.query(query)) ,你会看到我们得到了一个不同的查询(与 N 的 query.compile() 相比) - 带有子查询和别名。Query 来检查这一点对象,忽略 session 信息:from sqlalchemy.orm.query import Query
str(Query(query))
Query.__str__ )我们可以看到 发生了什么一个 是:context = Query(query)._compile_context()
str(context.statement.compile(bind=None))
context.statement.compile将尝试选择一种方言(在我们的例子中正确识别 Postgres),然后以与 相同的方式执行该语句。小号 变体:dialect.statement_compiler(dialect, context.statement, bind=None)
dialect = postgresql.dialect()
str(dialect.statement_compiler(dialect, query, bind=None))
dialect.statement_compiler 有什么用做,?它是 SQLCompiler 的子类的构造函数, 专门在继承过程中匹配您的方言需求;对于 Postgres,它应该是 PGCompiler .dialect.statement_compiler(dialect, Query(query).statement, bind=None)
__dict__ 轻松完成。编译器的属性:with_subquery = dialect.statement_compiler(dialect, context.statement, bind=None)
no_subquery = dialect.statement_compiler(dialect, query, bind=None)
from deepdiff import DeepDiff
DeepDiff(sub.__dict__, nosub.__dict__, ignore_order=True)
context.statement是 sqlalchemy.sql.selectable.Select对象,而在后者中 query是 sqlalchemy.sql.selectable.Alias目的。Query 的事实。对象 db.session.query() , 导致编译器根据语句的更改类型采取不同的路线。我们可以看到小号 事实上,它是一个包裹在选择中的别名,使用:>>> context.statement._froms
[<sqlalchemy.sql.selectable.Alias at 0x7f7e2f4f7160; foo>]
When an Alias is created from a Table object, this has the effect of the table being rendered as tablename AS aliasname in a SELECT statement.
.alias('foo') 的情况下命名查询如 电话 (无别名)并在下面的伪代码中表示为 n_query .因为它是类型 sqlalchemy.sql.selectable.Select当您拨打 db.session.query(n_query) 时它以与使用别名的情况大致相同的方式创建了一个子查询。您可以使用以下命令验证我们是否在另一个选择中获得了一个选择:>>> Query(nquery).statement._froms
[<sqlalchemy.sql.selectable.Select at 0x7f7e1e26e668; Select object>]
db.session.query(n_query) 查询数据库时始终创建了子选择。 .str(db.session(n_query)) 当时?db.session.execute(n_query)
db.session.execute(n_query.alias('foo'))
关于python - SQLAlchemy 要求为查询设置别名,但在生成的 SQL 中未使用该别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56040284/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h