Giter Site home page Giter Site logo

Comments (13)

josevalim avatar josevalim commented on September 13, 2024

I have looked into this and unfortunately I don't think there is an easy fix. Perhaps you can set it to prefix: prefix(), which is the default prefix?

from ecto_sql.

josevalim avatar josevalim commented on September 13, 2024

Nah, prefix() may return nil too. In order to fix this, we would need to change the .prefix field in index, table, reference and other structs to be {:ok, prefix} | :error or something of sorts. But this would be backwards incompatible.

from ecto_sql.

jdewar avatar jdewar commented on September 13, 2024

nothing super elegant, but ..

  • one backwards compatible option would be to have a no_prefix: true (remove_prefix, clear_prefix, etc) option that raised if you tried to set it and :prefix in the same opts.
  • another would be to allow prefix: to take something more complex than an atom/string, like {:clear, :prefix}
  • similar to previous idea, maybe it's okay to special case the false atom as clearing the prefix (you could still use "false" string if that was a desired prefix) oh right, hmm, not backwards compatible, this.

from ecto_sql.

SteffenDE avatar SteffenDE commented on September 13, 2024

The default schema on postgres databases is "public". So you should be able to write add(:group_id, references("group", prefix: "public")) in this case.

from ecto_sql.

greg-rychlewski avatar greg-rychlewski commented on September 13, 2024

The default schema on postgres databases is "public". So you should be able to write add(:group_id, references("group", prefix: "public")) in this case.

This is good advice. Maybe we should just document something like this as the solution. As far as I know you should always be able to write unqualified table names as qualified table names. In Postgres every table is inside of a schema. In MySQL every table is inside of a database.

It sounds better to me than introducing a new conflicting option or a backwards incompatible change.

from ecto_sql.

josevalim avatar josevalim commented on September 13, 2024

Yeah, it is just the behaviour is inconsistent with the other uses of prefixes, but there isn't much we can do I think.

from ecto_sql.

greg-rychlewski avatar greg-rychlewski commented on September 13, 2024

Is there any precedent to create a new function that is basically the old one but with the correct fix? And then deprecate the old one.

from ecto_sql.

josevalim avatar josevalim commented on September 13, 2024

From my exploration the issue is really the struct. So we need to change the struct which will break the adapters. It is not a major pain we can do it. And if we change it to {:ok, ...} | :error, adapters can easily handle the different types.

from ecto_sql.

greg-rychlewski avatar greg-rychlewski commented on September 13, 2024

Oh I think I see what you mean. The issue is here right:

quote_table(ref.prefix || table.prefix, ref.table)

So if ref.prefix is :error then we use table.prefix but if it is {:ok, nil} then we use the unprefixed quote_table function?

That looks good to me. I wasn't sure what the policy was about changing the behaviour of existing migrations or other adapters like SQLite, Clickhouse, etc. But if it's normal procedure then +1 from me.

from ecto_sql.

josevalim avatar josevalim commented on September 13, 2024

Typically we add new callbacks on major versions, which often breaks the adapter anyway, but it is very unoften that we change behaviour. That's why adding a new field to the struct, as mentioned by @jdewar, may be the best option? We can call it options, keep it as a keyword list, and shove :prefix there? So the code above becomes:

quote_table(Keyword.get(ref.options, :prefix, table.prefix), ref.table)

And we deprecate .prefix?

from ecto_sql.

greg-rychlewski avatar greg-rychlewski commented on September 13, 2024

That sounds like the best option to me. And the docs are pretty clear about he behaviour:

:prefix - The prefix for the reference. Defaults to the prefix defined by the block's table/2 struct (the "products" table in the example above), or nil.

So if someone was using prefix: nil to be the table's prefix then they were using it in error anyway.

from ecto_sql.

jdewar avatar jdewar commented on September 13, 2024

We were able to side step the problem by creating a new prefix, and using "public" would've been our solve (wouldn't've created this issue even, had I known). Thanks much for this change! It's nice to set prefix to 'nil' in a way that matches my mental model.

:prefix - The prefix for the reference. Defaults to the prefix defined by the block's table/2 struct (the "products" table in the example above), or nil.

So if someone was using prefix: nil to be the table's prefix then they were using it in error anyway.

@greg-rychlewski I did want to comment on this part; one might have the Application config define a :migration_default_prefix, and then a table's prefix: nil could make sense, eg:

config :myapp, Repo, migration_default_prefix: "my_prefix"

...

create table("user", prefix: nil) do
  add(:prefixed_group_id, references("prefixed_group", prefix: "my_prefix"))
end

from ecto_sql.

greg-rychlewski avatar greg-rychlewski commented on September 13, 2024

Yes sorry. I meant it's ok for us to "break" users who are relying on our mistake to have the migrations behave in an undocumented way.

from ecto_sql.

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.