简体   繁体   English

如何扩充SQLAlchemy中的声明式基础

[英]How to augment the declarative base in SQLAlchemy

I am following the SQLAlchemy Documentation by Mike Bayer and have a couple of issues when trying to augment the declarative_base as per code below. 我正在按照Mike Bayer的SQLAlchemy文档进行操作,并尝试按照下面的代码扩展declarative_base时遇到一些问题。

module db.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 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()

module db.model.testdata 模块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)

In the SQLAlchemy documentation the @classmethod annotation is not added to the tablename method in the Base class. 在SQLAlchemy文档中,@classmethod批注未添加到基类的tablename方法中。 However without it I get a "Method 'tablename - db.base' should have self as first parameter" error, basically saying that the @declared_attr is not marking the method as a class level method. 但是,如果没有它,我将收到“方法'tablename-db.base'应该具有self作为第一个参数”错误,基本上是说@declared_attr并未将该方法标记为类级别方法。 Are you supposed to add @classmethod or is this a bug in the version (0.9.8) I am using? 您应该添加@classmethod还是我正在使用的版本(0.9.8)中的错误?

The tablename returned by the base augmentor is cryptic "bound method DeclarativeMeta.? of class db.model.testdata.TestData" How can I get just the class name (TestData) returned? 基本增强器返回的表名是db.model.testdata.TestData类的“绑定方法DeclarativeMeta。?”,如何才能仅获得返回的类名(TestData)?

Another minor issue - the print() call in the tablename method in the Base class does not print anything (neither did logger) and I am not sure why. 另一个小问题-Base类的tablename方法中的print()调用不会打印任何内容(记录器也不会打印),而且我不确定为什么。

The reason I was getting a cryptic table name generated and why the print call wasn't working was that the tablename method in the Base class was not being called (due to having the @classmethod annotation). 我生成一个隐秘的表名的原因以及打印调用为何不起作用的原因是,未调用Base类中的tablename方法(由于具有@classmethod批注)。

The issue appears to be with PyDev. 问题似乎出在PyDev。 I ran the same code in PyCharm, PyCharm did not have an issue with the @declared_attr annotation and did not require @classmethod. 我在PyCharm中运行了相同的代码,PyCharm在@declared_attr批注中没有问题,并且不需要@classmethod。

In PyDev, I added sqlalchemy to the forced builtins (Window ->Preferences ->PyDev ->Interpreters ->Python interpreter ->Forced Builtins). 在PyDev中,我将sqlalchemy添加到了强制内置程序(“窗口->首选项-> PyDev->解释器-> Python解释器->强制内置程序”)。 I then removed the @classmethod anotation and re-ran it. 然后,我删除了@classmethod注释并重新运行它。 I still get an 'Method tablename - db.base should have self as first parameter' error marker on the code but it runs OK now. 我仍然在代码上得到“方法表名 -db.base应该以self作为第一个参数”错误标记,但现在可以正常运行了。

I still get an 'Method tablename - db.base should have self as first parameter' error marker on the code but it runs OK now. 我仍然在代码上得到“方法表名-db.base应该以self作为第一个参数”错误标记,但现在可以正常运行了。

If that bothers you, having the cursos over the error pointed by PyDev, you can press Control+1 and mark the line as # @NoSelf . 如果这让您感到烦恼,并且对PyDev指出的错误感到好奇,则可以按Control+1并将该行标记为# @NoSelf This informs PyDev that your method does not have self as its first parameter. 这通知PyDev您的方法没有以self作为其第一个参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM