如何在SQLAlchemy中扩充声明性基础

时间:2014-12-28 21:55:06

标签: python sqlalchemy

我正在关注Mike Bayer撰写的SQLAlchemy文档,并且在尝试根据下面的代码扩充declarative_base时遇到了一些问题。

模块db.base

from sqlalchemy.ext.declarative import declared_attr
from sqlalchemy import Column, Date, Integer, String

class Base(object):
    @classmethod
    @declared_attr
    def __tablename__(cls):
        print(">>__tablename__() "+str(cls.__name__.lower()))
        return cls.__name__.lower()
    id = Column(Integer, primary_key=True, nullable = False)
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base(cls=Base)

module db.dbtest

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from db.base import Base
engine = create_engine('sqlite:////tmp/test.db', echo=True)
db_session = scoped_session(sessionmaker(autocommit=False,
                                autoflush=False,
                                bind=engine))

def init_db():
    import db.model.testdata 
    base = Base()
    base.metadata.create_all(bind=engine)

if __name__ == '__main__':
   init_db()

模块db.model.testdata

from db.base import Base
from sqlalchemy import Boolean, Column, Date, Integer, String
from sqlalchemy import REAL

class TestData(Base):
    name = Column(String(255), nullable = False)
    creationDate =  Column(Date, index=True)
    updateDate =  Column(Date, index=True)
    miscData = Column(REAL, nullable = True)

在SQLAlchemy文档中,@ classmethod注释未添加到Base类的tablename方法中。但是如果没有它,我会得到一个"方法' tablename - db.base'应该将自己作为第一个参数"错误,基本上说@declared_attr没有将方法标记为类级方法。您是否应该添加@classmethod或者这是我正在使用的版本(0.9.8)中的错误?

基础扩充器返回的表名是神秘的"绑定方法DeclarativeMeta。? db.model.testdata.TestData类#34;我怎样才能获得返回的类名(TestData)?

另一个小问题 - Base类中tablename方法中的print()调用不打印任何内容(记录器也没有),我不确定原因。

2 个答案:

答案 0 :(得分:0)

我生成一个神秘的表名称的原因以及打印调用无法正常工作的原因是Base类中的tablename方法未被调用(由于具有@classmethod注释)。

这个问题似乎与PyDev有关。我在PyCharm中运行了相同的代码,PyCharm没有@declared_attr注释的问题,并且不需要@classmethod。

在PyDev中,我将sqlalchemy添加到强制内置函数中(Window - > Preferences - > PyDev - > Interpreters - > Python解释器 - > Forced Builtins)。然后我删除了@classmethod anotation并重新运行它。我仍然得到一个'方法 tablename - db.base应该将self作为第一个参数'代码上的错误标记但现在运行正常。

答案 1 :(得分:0)

  

我仍然得到一个'方法表名 - db.base应该首先使用self   参数'代码上的错误标记但现在运行正常。

如果这让你烦恼,对PyDev指出的错误进行了游说,你可以按Control+1并将该行标记为# @NoSelf。这告诉PyDev你的方法没有self作为它的第一个参数。