我正在开发一个库,用户可以简单地声明一些由数据库自动支持的类.简而言之,隐藏在代码中的某个地方就有了
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class LibraryBase(Base):
# important library stuff
Run Code Online (Sandbox Code Playgroud)
然后用户应该这样做
class MyStuff(LibraryBase):
# important personal stuff
class MyStuff_2(LibraryBase):
# important personal stuff
mystuff = MyStuff()
Library.register(mystuff)
mystuff.changeIt() # apply some changes to the instance
Library.save(mystuff) # and save it
# same for all other classes
Run Code Online (Sandbox Code Playgroud)
在静态环境中,例如用户创建了一个包含所有个人类的文件并导入了该文件,这非常有效.所有类名都是固定的,SQLAlchemy知道如何映射每个类.
在交互式环境中,事情是不同的:现在,有可能两次定义一个类.这两个类可能有不同的模块; 但SQLAlchemy仍会抱怨:
SAWarning:类名'MyStuff'已经在此声明基础的注册表中,映射到<class'Othermodule.MyStuff'>
有办法解决这个问题吗?我可以以某种方式从它卸载一个类,declarative_base
以便我可以用一个新的交换它的定义吗?
我有一个表用户和一个表朋友将用户映射到其他用户,因为每个用户可以有很多朋友.这种关系显然是对称的:如果用户A是用户B的朋友,那么用户B也是用户A的朋友,我只存储一次这种关系.除了两个用户ID之外,Friends表还有其他字段,因此我必须使用关联对象.
我试图在Users类中声明这种关系(扩展声明基础),但我似乎无法弄清楚如何做到这一点.我希望能够通过房产朋友访问给定用户的所有朋友,所以说朋友= bob.friends.
这个问题的最佳方法是什么?我试着在这里发布许多不同的设置,但是由于各种原因它们都没有工作.
编辑:我的最新尝试看起来像这样:
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
# Relationships
friends1 = relationship('Friends', primaryjoin=lambda: id==Friends.friend1ID)
friends2 = relationship('Friends', primaryjoin=lambda: id==Friends.friend2ID)
class Friends(Base):
__tablename__ = 'friends'
id = Column(Integer, primary_key=True)
friend1ID = Column(Integer, ForeignKey('users.id') )
friend2ID = Column(Integer, ForeignKey('users.id') )
status = Column(Integer)
# Relationships
vriend1 = relationship('Student', primaryjoin=student2ID==Student.id)
vriend2 = relationship('Student', primaryjoin=student1ID==Student.id)
Run Code Online (Sandbox Code Playgroud)
但是会导致以下错误:
InvalidRequestError: Table 'users' is already defined for this MetaData instance. Specify 'extend_existing=True' to redefine options and columns on an existing Table …
Run Code Online (Sandbox Code Playgroud) 我读了一篇关于Prolog和Logic Programming的简短文章.我很好奇逻辑程序是否可以进行代数.就像你能问出X的变量在等式5 + X = 7中得到什么并得到-2的答案?
我想使用自动加载来使用现有数据库.我知道如何在没有声明性语法(model/_ init _.py)的情况下执行此操作:
def init_model(engine):
"""Call me before using any of the tables or classes in the model"""
t_events = Table('events', Base.metadata, schema='events', autoload=True, autoload_with=engine)
orm.mapper(Event, t_events)
Session.configure(bind=engine)
class Event(object):
pass
Run Code Online (Sandbox Code Playgroud)
这工作正常,但我想使用声明性语法:
class Event(Base):
__tablename__ = 'events'
__table_args__ = {'schema': 'events', 'autoload': True}
Run Code Online (Sandbox Code Playgroud)
不幸的是,这样我得到:
sqlalchemy.exc.UnboundExecutionError:没有引擎绑定到此Table的MetaData.通过autoload_with = <someengine>将引擎传递给表,或通过metadata.bind = <someengine>将MetaData与引擎相关联
这里的问题是我不知道在导入模型的阶段从哪里获取引擎(在autoload_with中使用它)(它在init_model()中可用).我尝试添加
meta.Base.metadata.bind(engine)
Run Code Online (Sandbox Code Playgroud)
到environment.py但它不起作用.有人找到了一些优雅的解决方案
f和g的组成看起来像
f :. g = \a b -> f (g a) (g b)
Run Code Online (Sandbox Code Playgroud)
是我在代码中经常发现的模式.它类似于一元函数组合,只是f
二进制,我希望g
在它们传递给它们之前应用于两个参数f
.
当我要求lambdabot将其转换为无点形式时,我得到了奇怪的咒语
flip ((.) . f . g) g
Run Code Online (Sandbox Code Playgroud)
在我的代码中我不想拥有它,所以我最终只是明确地写出了模式.
是否有一种普遍接受的方法来为这种情况编写组合子?或者我在这种情况下发现自己很奇怪?
我现在没有一个实际的例子,因为当我需要时,我从未想过要问这里,但可以想象用它非常整齐地写出欧几里德距离公式,就像这样:
distance = sqrt . (+) :. (^2)
Run Code Online (Sandbox Code Playgroud) 我正在构建一个 api,如果用户请求它可以返回资源的子级。例如,user
有messages
. 我希望查询能够限制message
返回的对象数量。
我发现了一个有用的技巧aboutl imiting在子集合对象的数量在这里。基本上,它表示以下流程:
class User(...):
# ...
messages = relationship('Messages', order_by='desc(Messages.date)', lazy='dynamic')
user = User.query.one()
users.messages.limit(10)
Run Code Online (Sandbox Code Playgroud)
我的用例涉及有时会返回大量用户。
如果我要遵循该链接中的建议并使用,.limit()
那么我将需要遍历调用.limit()
每个用户的整个用户集合。这比LIMIT
在创建集合的原始 sql 表达式中使用效率低得多。
我的问题是,是否有可能使用声明来有效地(N+0)加载大量对象,同时使用 sqlalchemy 限制其子集合中的子集合的数量?
更新
需要明确的是,以下是我试图避免的。
users = User.query.all()
messages = {}
for user in users:
messages[user.id] = user.messages.limit(10).all()
Run Code Online (Sandbox Code Playgroud)
我想做一些更像:
users = User.query.option(User.messages.limit(10)).all()
Run Code Online (Sandbox Code Playgroud) 我想知道是否存在任意描述数据结构的格式和语义的声明性语言,可以在任何一组目标语言中编译成该结构的特定实现.也就是说,类似于通用数据定义语言,但旨在描述任意数据结构,如向量,列表,树等,以及对这些结构的操作语义.我问,因为我有一个关于这个概念的可行实现的想法,我只是想知道它是否值得,因此,它是否已经完成.
另一个稍微抽象的问题是:数据结构的规范性规范(它的作用)与其实现(它是如何实现的)之间是否存在真正的差异?更具体地说,是否应将相同要求的单独实施视为不同的结构?
我正在寻找的是一个基本的操作(我肯定有一个名字,我只是没有意识到atm).我有一个矩阵像:
{1,2,3}
{A,N,F}
{7,8,9}
我想改变它
{1,A,7}
{2,N,8}
{3,F,9}
(以上只是对象的标识符而不是实际值.实际对象属于同一类型且无序)
我更喜欢它的声明性解决方案,但速度是一个因素.我将不得不转动相当多的表(每分钟100k个单元),而慢速版将在关键路径上.
但是我对可读解决方案仍然更感兴趣.我正在寻找下面的替代解决方案.(换句话说,我不是指变化,而是一种不同的方法)
var arrays = rows.Select(row => row.ToArray());
var cellCount = arrays.First().Length;
for(var i = 0;i<cellCount;i++){
yield return GetRow(i,arrays);
}
IEnumerable<T> GetRow(int i,IEnumerable<T[]> rows){
foreach(var row in rows}{
yield return row[i];
}
}
Run Code Online (Sandbox Code Playgroud)
在两个几乎同样可读的解决方案中,我会更快,但可读性在速度之前
编辑 它将始终是一个方阵
我希望创建一个从另一个表填充的对象的映射属性.
使用SQLAlchemy文档示例,我希望在Address类中存在一个user_name字段,以便可以轻松查询和轻松访问它(无需第二次往返数据库)
例如,我希望能够查询和过滤user_name
Address.query.filter(Address.user_name == 'wcdolphin').first()
并且还可以访问user_name
所有Address对象的属性,而不会降低性能,并使其正确保持写入,就像预期的属性一样.__tablename__
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(50))
addresses = relation("Address", backref="user")
class Address(Base):
__tablename__ = 'addresses'
id = Column(Integer, primary_key=True)
email = Column(String(50))
user_name = Column(Integer, ForeignKey('users.name'))#This line is wrong
Run Code Online (Sandbox Code Playgroud)
我该怎么做呢?
我发现文档相对难以理解,因为它似乎不符合大多数示例,尤其是Flask-SQLAlchemy示例.
在SQLAlchemy中,我已经阅读了__table_args__
在声明声明时如何组合来自不同mixin的内容.
我的问题是,这个例子说明了如何在链的末尾(MRO中的最后一个类)完成这个,但是如果我有这些Mixins并希望它出现在MyClientMixin
或者Base
类中,怎么会实现这个呢?避免为其他类型的mixin复制此代码?
class LaneCarrierCommitmentSummaryMixin(object):
""" Lane Carrier Commitment Summary.
A base class for LCCS to mixin with a client specific class.
"""
__tablename__ = 'lane_carrier_commitment_summary'
__table_args__ = ((UniqueConstraint(['hashmap_key', 'bow'],
name='uq_lane_carrier_commitment_summary_hashmap_key_bow')),)
class MyClientMixin(object):
""" MyClient Mixin class for providing the ETL schema. """
__table_args__ = {'schema': 'myclient_etl'}
class MyClientLaneCarrierCommitmentSummary(LaneCarrierCommitmentSummaryMixin, DateTrackedMixin, MyClientMixin, Base):
pass
Run Code Online (Sandbox Code Playgroud)
我对这个概念有点挣扎.
declarative ×10
python ×6
sqlalchemy ×6
orm ×2
algebra ×1
algorithm ×1
c# ×1
class ×1
clpfd ×1
clpq ×1
haskell ×1
limit ×1
linq ×1
many-to-many ×1
mapping ×1
pointfree ×1
prolog ×1
pylons ×1
reflection ×1
relationship ×1