我有一个数据库模型,我需要一对多的关系和两个一对一的关系。这是我制作的模型,但是它会抛出错误
class Page(Base):
__tablename__ = 'pages'
id = Column(Integer, primary_key=True)
title = Column(String(100), nullable=False)
content = Column(Text, nullable=False)
parent_id = Column(Integer, ForeignKey("pages.id"), nullable=True)
children = relationship("Page", backref=backref("parent", remote_side=id))
next_id = Column(Integer, ForeignKey("pages.id"), nullable=True)
next = relationship("Page", backref=backref("prev", remote_side=id, uselist=False))
prev_id = Column(Integer, ForeignKey("pages.id"), nullable=True)
prev = relationship("Page", backref=backref("next", remote_side=id, uselist=False))
def __init__(self, title, content, parent_id=None, next_id=None, prev_id=None):
self.title = title
self.content = content
self.parent_id = parent_id
self.next_id = next_id
self.prev_id = prev_id
def __repr__(self):
return '<Page "%r">' % self.title
每当我尝试对数据库执行任何操作时,我都会收到以下错误
ArgumentError: Could not determine join condition between parent/child tables on relationship Page.children. Specify a 'primaryjoin' expression. If 'secondary' is present, 'secondaryjoin' is needed as well.
真正奇怪的是它没有下一个和上一个列的工作。有人知道什么是错的吗?
答案 0 :(得分:14)
这个主题已经过时了,但由于这太令人困惑,我会把它写下来 你不需要单独的'prev'列,你已经将它作为'next'的backref。 此外,由于同一目标有多个外键,因此需要手动指定主连接:
class Page(Base):
__tablename__ = 'pages'
id = Column(Integer, primary_key=True)
title = Column(String(100), nullable=False)
content = Column(Text, nullable=False)
parent_id = Column(Integer, ForeignKey("pages.id"), nullable=True)
parent = relationship("Page",
primaryjoin=('pages.c.id==pages.c.parent_id'),
remote_side='Page.id',
backref=backref("children" ))
next_id = Column(Integer, ForeignKey("pages.id"), nullable=True)
next = relationship("Page",
primaryjoin=('pages.c.next_id==pages.c.id'),
remote_side='Page.id',
backref=backref("prev", uselist=False))
我注意到了一些错误或一些奇怪的行为:
- 您只能使用remote_side="Page.id"
,而不是remote_side=[id]
而不是remote_side=["Page.id"]
,否则它将无效(sqlalchemy 0.6.6)。这很令人讨厌
- 看起来您应始终使用remote_side
主键,无论您的实际远程端是什么。即使看起来合适,remote_side="Pages.next_id"
也会产生奇怪的错误
- primaryjoin表达式令人困惑,因为它不使用别名,但这实际上是正确的方法。绑定引擎知道要用参数替换哪个表达式(这太隐含了,反对Zen,顺便说一句)。
答案 1 :(得分:1)
您可以使用import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Scanner;
public class FileLoader {
public static Reader openReader(String filename, boolean isResource) throws UnsupportedEncodingException, FileNotFoundException, MalformedURLException {
return openReader(filename, isResource, "UTF-8");
}
public static Reader openReader(String filename, boolean isResource, String charset) throws UnsupportedEncodingException, FileNotFoundException, MalformedURLException {
return new InputStreamReader(openInputStream(filename, isResource), charset);
}
public static InputStream openInputStream(String filename, boolean isResource) throws FileNotFoundException, MalformedURLException {
if (isResource) {
return FileLoader.class.getClassLoader().getResourceAsStream(filename);
}
return new FileInputStream(load(filename, isResource));
}
public static String read(String path, boolean isResource) throws IOException {
return read(path, isResource, "UTF-8");
}
public static String read(String path, boolean isResource, String charset) throws IOException {
return read(pathToUrl(path, isResource), charset);
}
@SuppressWarnings("resource")
protected static String read(URL url, String charset) throws IOException {
return new Scanner(url.openStream(), charset).useDelimiter("\\A").next();
}
protected static File load(String path, boolean isResource) throws MalformedURLException {
return load(pathToUrl(path, isResource));
}
protected static File load(URL url) {
try {
return new File(url.toURI());
} catch (URISyntaxException e) {
return new File(url.getPath());
}
}
private static final URL pathToUrl(String path, boolean isResource) throws MalformedURLException {
if (isResource) {
return FileLoader.class.getClassLoader().getResource(path);
}
return new URL("file:/" + path);
}
}
:
foreign_keys