将python sqlalchemy类转换为原始SQL(使用外键创建表)

时间:2018-05-28 10:20:27

标签: python sql postgresql sqlalchemy

我有一个python应用程序,我使用sqlalchemy和posgreSQL。我已经在数据库中有一些数据并且不想重新创建它,所以我想在数据库中添加一个表并保留所有数据(之前我使用了alembic,但是这次我想使用原始SQL)。 / p>

这是我的新表,我想在python中添加到数据库中:

# User payed data
class UserPayData(Base):
    __tablename__ = 'userspaydata'
    id = Column(Integer, primary_key=True) 
    account_owner = Column(Text, nullable=False)
    IBAN = Column(Text, nullable=False)
    # Foreign Keys
    belongs_to_user_id = Column(Integer, ForeignKey('users.id'))
    payment_belongs_to_user_relation = relationship("User", back_populates="payment_belongs_to_user_addresses")

    def __init__(self, account_owner=None, IBAN=None):
        self.account_owner = account_owner
        self.IBAN = IBAN

    def get(self, id):
        if self.id == id:
            return self
        else:
            return None

    def __repr__(self):
        return '<%s(%r, %r, %r)>' % (self.__class__.__name__, self.id, self.account_owner, self.IBAN)

以下是users表中的相关部分:

# Project
class User(UserMixin, Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    # etc...
    # Foreign Key payment
    payment_belongs_to_user_addresses = relationship('UserPayData', back_populates="payment_belongs_to_user_relation")

这是我想要执行的原始SQL:

CREATE TABLE 'userspaydata'
(
    account_owner TEXT NOT NULL,
    IBAN TEXT NOT NULL,
    belongs_to_user_id INT references users(id)
);

我找到了很多例子,有些例子不同。

我有几个问题:

我是否还必须创建主键? AFAIK,如果我没有定义主键,它将自动ID INT

不需要在数据库级别定义关系,它们是在应用程序级别定义的,还是我错了?如果我错了,我如何在原始SQL中定义关系?

我还没有提交SQL查询,语法是否正确?

2 个答案:

答案 0 :(得分:2)

  

我是否必须创建主键

是的,如果你想使用sqlalchemy声明映射来处理这些表,一般来说指定主键是个好主意。

  

不需要在数据库级别定义关系,它们是在应用程序级别定义的,还是我错了?

Sqlalchemy Declarative类中定义的外键被映射到数据库外键约束。

同样,关系数据库中的关系是另一个好主意。除非您有特殊原因,否则请指定外键依赖项。

如果未在数据库中指定约束,则最终可能会损坏数据。

如果要手动发出DDL语句,则可以指定外键约束。 Foreign Keys in the Postgres Documentation

  

我还没有提交SQL查询,语法是否正确?

不,这是您的DDL声明的更正版本。

CREATE TABLE userspaydata (
  id INTEGER PRIMARY KEY,
  account_owner TEXT NOT NULL,
  IBAN TEXT NOT NULL,
  belongs_to_user_id INT references users(id) -- this is a FK constraint
);

请注意id不会自动增加。对于auto-increment id

id列定义更改为

-- postgrseql 10 & above
id INTEGER PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY
-- postgresql 9.6 & below
id SERIAL PRIMARY KEY

并将id列的sqlalchemy映射更改为

id = Column(Integer, primary_key=True, auto_increment=True)

答案 1 :(得分:0)

这是我的解决方案,似乎有效(我还添加了日期时间):

CREATE TABLE userspaydata (
    Id SERIAL primary key,
    account_owner TEXT NOT NULL,
    IBAN TEXT NOT NULL,
    date_added TIMESTAMP WITH TIME ZONE,
    belongs_to_user_id INT references users(id)
);

PK必须由我定义。

关系在应用级别处理。