Giter VIP home page Giter VIP logo

Comments (7)

olirice avatar olirice commented on May 27, 2024

Given that check constraints may only reference the current row, the limit on complexity is pretty low. You can avoid the problem by defining the logic directly in the check constraint rather than in a function.

for example

-- Example table with check constraint
create table foo(
	id serial primary key,
	-- Ensure that bar has value > 5
	bar int constraint ck check (bar > 5)
);

-- Add a row that satisfies the constraint
insert into foo(bar) values (6);

-- Remove existing constraint
alter table foo drop constraint ck;

-- Add new constraint that is violated by existing row
alter table foo add constraint ck check (bar > 10);

/*
Result: ERROR:  check constraint "ck" is violated by some row
*/

But, if you're sure you want to use a function

-- Set up your function
create function gte_thresh(val int) returns bool
as $$ select val > 5 $$ language sql;

-- Example table using your function
create table foo(
	id serial primary key,
	bar int constraint ck check (gte_thresh(bar))
);

-- Add a row that satisfies the constraint
insert into foo(bar) values (6);

-- Update check constraint function so that an existing record fails
create or replace function gte_thresh(val int) returns bool
as $$ select val > 10 $$ language sql;
-- There is now an existing row that violates the check constraint

You can then drop and recreate the check constraint to get the behavior you want by adding this to the bottom of your migration

-- Remove existing constraint
alter table foo drop constraint ck;
-- Add new constraint that is violated by existing row
alter table foo add constraint ck check (gte_thresh(bar));

/*
Result: ERROR:  check constraint "ck" is violated by some row
*/

from alembic_utils.

adrianschneider94 avatar adrianschneider94 commented on May 27, 2024

Ahh, I didn‘t make my point clear enough...
The point are autogenerated migrations.
My target is:

  • I want to change the constraint
  • So I change the function
  • I run alembic revision --autogenerate
  • A migration is generated, where the function is updated, the check constraint dropped and recreated

And now I‘m looking for an easy way to register the check constraint with the function.
And before digging deeper into your code to see what happens, I thought I ask if you see a quick and easy way.

All because check constraints are not included in auto generation at the moment.

Thanks,
Adrian

from alembic_utils.

olirice avatar olirice commented on May 27, 2024

Check constraints do work with autogenerate in alembic core if you provide a name for them.

Why adding names is necessary is outlined here:
https://alembic.sqlalchemy.org/en/latest/naming.html

That would be the only way to get it working in a way you'll be happy with right now

Example:

class Foo(Base):

    __tablename__ = 'foo'
    __table_args__ = (
        CheckConstraint("bar > 10", name="ck_foo_bar"),
    )

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

Longer term I plan to use pg_depend to optionally identify, drop and recreate dependent objects during migrations with an api similar to

def upgrade():
    my_view = PGView(...)
   
    with defer_dependent_objects(my_view):
        op.replace_entity(my_view)

To make migrating views with dependencies easier. The dependency resolver required for that functionality would likely also work for your use case.

I'll let you know if that materializes

from alembic_utils.

adrianschneider94 avatar adrianschneider94 commented on May 27, 2024

No, it isn‘t as far as I‘m aware, that‘s the point. Or did I misunderstand something terribly wrong? I would be happy if that was the case 😄

sqlalchemy/alembic#508

So I guess I have to take the long way...

from alembic_utils.

olirice avatar olirice commented on May 27, 2024

Interesting link

I was wrong that updates to check constraints are detected. That make sense given that they're written as strings

But that wouldn't solve your problem if the logic is hidden behind a function because the check constraint wouldn't change when the function changes and alembic doesn't resolve dependencies.

Or was your "put it behind a function" approach a workaround to changes in check constraints not being detected?

from alembic_utils.

adrianschneider94 avatar adrianschneider94 commented on May 27, 2024

Yes exactly. This was the idea. Put the logic into a function and add hooks that drop and recreate constraints that depend on the function.
At the moment I do that manually.

from alembic_utils.

olirice avatar olirice commented on May 27, 2024

Closing as out-of-scope

from alembic_utils.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.