- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个代表业务单元的 cython 类。此类以纯 cython 风格声明。
在一个项目中,我需要将业务单元映射到数据库。为此,我想导入 .pxd 文件并使用 SQLAlchemy“映射”它。
让我们假设类 Equipment。该类定义为 .pyx 和 .pxd 中的类接口(interface)(因为我需要在其他模块中导入它)。
cdef class Equipment:
cdef readonly int x
cdef readonly str y
cdef class Equipment:
def __init__(self, int x, str y):
self.x = x
self.y = y
我编译所有内容并得到一个 equipment.pyd 文件。到目前为止,没问题。此文件包含业务逻辑模型,不得更改。
然后在一个应用程序中,我导入 equipment.pyd 并用 SQLAlchemy 映射它。
from sqlalchemy import Table, Column, Integer, String
from sqlalchemy.orm import mapper
from equipment import Equipment
metadata = MetaData()
# Table definition
equipment = Table(
'equipment', metadata,
Column('id', Integer, primary_key=True),
Column('x', Integer),
Column('y', String),
)
# Mapping the table definition with the class definition
mapper(Equipment, equipment)
TypeError: can't set attributes of built-in/extension type 'equipment.Equipment'
确实,SQLAlchemy 正在尝试创建 Equipment.c.x、Equipment.c.y,...这在 Cython 中是不可能的,因为它未在 .pxd 中定义...
那么如何将 Cython 类映射到 SQLAlchemy?
如果我在 .pyx 文件中以 python 模式定义设备类,它会起作用,因为最后,它只是 cython 类定义中的“python”对象。
class Equipment:
def __init__(self, x, y):
self.x = x
self.y = y
但我失去了很多功能,这就是为什么我需要纯 Cython。
谢谢! :-)
-- 编辑部分 --
保留 .pyx 和 .pxd 文件。从 .pyd 继承。尝试映射。
from sqlalchemy import Table, Column, Integer, String
from sqlalchemy.orm import mapper
from equipment import Equipment
metadata = MetaData()
# Table definition
equipment = Table(
'equipment', metadata,
Column('id', Integer, primary_key=True),
Column('x', Integer),
Column('y', String),
)
# Inherit Equipment to a mapped class
class EquipmentMapped(Equipment):
def __init__(self, x, y):
super(EquipmentMapped, self).__init__(x, y)
# Mapping the table definition with the class definition
mapper(EquipmentMapped, equipment)
from mapping import EquipmentMapped
e = EquipmentMapped(2, 3)
print e.x
## This is empty!
为了让它工作,我必须将每个属性定义为属性!
cdef class Equipment:
cdef readonly int _x
cdef readonly str _y
cdef class Equipment:
def __init__(self, int x, str y):
self.x = x
self.y = y
property x:
def __get__(self):
return self._x
def __set__(self, x):
self._x = x
property y:
def __get__(self):
return self._y
def __set__(self, y):
self._y = y
这并不令人满意,因为 :lazy_programmer_mode on: 我在业务逻辑中有很多更改要做... :lazy_programmer_mode off:
最佳答案
我认为最基本的问题是,当你调用 mapper
时,它会(除其他外)
Equipment.x = ColumnProperty(...) # with some arguments
Equipment.y = ColumnProperty(...)
当 ColumnProperty
是一个 sqlalchemy 定义的属性时,所以当您执行 e.x = 5
时,它会注意到该值已更改,因为它周围的所有数据库相关的东西.
这显然不能与您试图用来控制存储的下面的 Cython 类配合得很好。
就个人而言,我怀疑唯一真正的答案是定义一个包含 Cython 类和 sqlalchemy 映射类的包装类,并拦截所有属性访问和方法调用以保持它们同步。下面是一个粗略的实现,它应该适用于简单的情况。虽然它几乎没有经过测试,所以几乎可以肯定有它遗漏的错误和极端情况。当心!
def wrapper_class(cls):
# do this in a function so we can create it generically as needed
# for each cython class
class WrapperClass(object):
def __init__(self,*args,**kwargs):
# construct the held class using arguments provided
self._wrapped = cls(*args,**kwargs)
def __getattribute__(self,name):
# intercept all requests for attribute access.
wrapped = object.__getattribute__(self,"_wrapped")
update_from = wrapped
update_to = self
try:
o = getattr(wrapped,name)
except AttributeError:
# if we can't find it look in this class instead.
# This is reasonable, because there may be methods defined
# by sqlalchemy for example
update_from = self
update_to = wrapped
o = object.__getattribute__(self,name)
if callable(o):
return FunctionWrapper(o,update_from,update_to)
else:
return o
def __setattr__(self,name,value):
# intercept all attempt to write to attributes
# and set it in both this class and the wrapped Cython class
if name!="_wrapped":
try:
setattr(self._wrapped,name,value)
except AttributeError:
pass # ignore errors... maybe bad!
object.__setattr__(self,name,value)
return WrapperClass
class FunctionWrapper(object):
# a problem we have is if we call a member function.
# It's possible that the member function may change something
# and thus we need to ensure that everything is updated appropriately
# afterwards
def __init__(self,func,update_from,update_to):
self.__func = func
self.__update_from = update_from
self.__update_to = update_to
def __call__(self,*args,**kwargs):
ret_val = self.__func(*args,**kwargs)
# for both Cython classes and sqlalchemy mappings
# all the relevant attributes exist in the class dictionary
for k in self.__update_from.__class__.__dict__.iterkeys():
if not k.startswith('__'): # ignore private stuff
try:
setattr(self.__update_to,k,getattr(self.__update_from,k))
except AttributeError:
# There may be legitmate cases when this fails
# (probably relating to sqlalchemy functions?)
# in this case, replace raise with pass
raise
return ret_val
要使用它,您需要执行以下操作:
class EquipmentMapped(wrapper_class(Equipment)):
# you may well have to define __init__ here
# you'll have to check yourself, and see what sqlalchemy does...
pass
mapper(EquipmentMapped,equipment)
请记住,这是一个可怕的工作区,它基本上只是在两个地方复制所有数据,然后拼命尝试保持同步。
编辑:这个的原始版本提供了一种机制来自动执行一系列查询 OP 曾尝试过但决定手动完成很多工作(在 Cython 类上定义属性,它只会成功在覆盖 sqlalchemy 的跟踪更改机制中)进一步测试确认它不起作用。如果您对不该做什么感到好奇,请查看编辑历史记录!
关于python - 混合 Cython 类和 SqlAlchemy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29960673/
我正在尝试创建一个使用 UUID 作为主键的用户模型: from src.db import db # SQLAlchemy instance import sqlalchemy_utils impo
在 sqlalchemy 中,我试图合并表,然后使用 WHERE 和 ORDER_BY 创建别名 有点像 SELECT * FROM ( SELECT [TABLE_ONE].[SOME_ID]
我正在使用 SQL Alchemy(通过 Flask_sqlalchemy)将 Python 字典列表插入到 Postgres 数据库中。 其中一个表是所有唯一项目的列表(表 1),而第二个是与某个项
This source详细说明如何使用关联代理创建具有 ORM 对象值的 View 和对象。 但是,当我附加一个与数据库中现有对象匹配的值(并且所述值是唯一的或主键)时,它会创建一个冲突的对象,因此我
SQLAlchemy Core和SQLAlchemy ORM的目的有什么区别? 最佳答案 顾名思义,ORM是一个对象关系映射器:其目的是将数据库关系表示为Python对象。 核心是查询构建器。其目的是
带有ForeignKey的Column是否自动创建索引? 还是我需要手动添加index=True? some_field = Column(Integer, ForeignKey(SomeModel.
我有一个主数据库,每个客户自己的数据库连接存储在其中。 因此,每个客户端都使用2个db:main和它自己的db,必须确定其连接 对于每个http调用。我如何使用flask-sqlalchemy扩展名执
当我仅对类进行继承时,它才起作用 class User(Base): __tablename__ = ’users’ id = Column(Integer, primary_key=
从用户的角度来看,SQLAlchemy 的查询日志似乎有点过于冗长,有时甚至有点神秘: 2015-10-02 13:51:39,500 INFO sqlalchemy.engine.base.Engi
我正在尝试使用 wtforms.ext.sqlalchemy QuerySelectMultipleField 显示复选框列表,但我无法在 GET 的表单上显示模型数据。 这是我的models.py
我想为查询返回一个中继连接。使用标准的 graphene-sqlalchemy 你可以这样做: class Query(graphene.ObjectType): node = relay.N
我在 centos 7.5 虚拟机上部署了最新的 Airflow ,并将 sql_alchemy_conn 和 result_backend 更新到 postgresql 实例上的 postgres
我想将多个项目插入到一个表中,并在发生冲突时更新该表。这是我想出的以下内容 from sqlalchemy.dialects.postgresql import insert meta = MetaD
我有以下模型: class Item(Base): a = relationship() b = relationship() c = relationship() d
我有 presto 和 superset 设置。 presto 运行良好,可以通过命令访问: ./app/hadoop/setjdk8.sh;bin/presto-cli --server http:
我一直在寻找一种在 sqlalchemy 中使用 tsvector 的方法(就像 INTEGER 等其他方法一样),但到目前为止我还不清楚如何做到这一点。我读过可以使用 UserDefinedType
我正在使用 sqlalchemy(现在使用 sqlite,但稍后可能会改变)来构建一个数据库,其中插入的顺序和 rowids 很重要。我基本上有以下几点: class Message(Base):
给定一个对象,我想知道如何知道它是否是 sqlalchemy 映射模型的实例。 通常,我会使用 isinstance(obj, DeclarativeBase)。但是,在这种情况下,我没有可用的 De
我已经通读了查询文档,如果有办法从查询中获取表名,就看不到任何地方 - 例如如果我有 q = query(Users) ,我可以得到Users从 q 退出? 最佳答案 请注意,像您这样的事件简单查询可
我不确定如何定义create schema foo迁移?我的模型如下所示(我正在使用Flask-Migrate): class MyTable(db.Model): __tablename__
我是一名优秀的程序员,十分优秀!