22

I want to list the sources of a piece of information. Instead of creating another table with a one to many relation, I tought I'd use the Array type.

To I tried:

app = Flask(__name__)
db = SQLAlchemy(app)

...

class Edge(db.Model):

    sources = db.Column(
        db.ARRAY(db.String),
        default=db.ARRAY(db.String)
    )

But adding an edge gives me this error:

ProgrammingError: (psycopg2.ProgrammingError) can't adapt type 'ARRAY' [SQL: 'INSERT INTO edges (child_id, parent_id, sources) VALUES (%(child_id)s, %(parent_id)s, %(sources)s'] [parameters: {'child_id': 20, 'parent_id': 26, 'sources': ARRAY(String())}]

I can't find a good tutorial on how to use an array column with a default empty array.

Thanks

3 Answers 3

31

I eventually found the answer in the comments here:

sources = db.Column(
    db.ARRAY(db.String),
    server_default="{}"
)
Sign up to request clarification or add additional context in comments.

2 Comments

I wonder how to do this in the new declarative world of Mapped[list | None]
@LondonRob, leveraging default_factory=list. More details in the proposed answer.
2

A python callable can also be set as default value:

sources = db.Column(
    db.ARRAY(db.String),
    default=dict
)

2 Comments

It can, but for the OP's use-case it should be default=list.
Note that the default= argument differs in meaning from the server_default= argument. The former is evaluated only on the Python side, whereas the latter is evaluated inside PostgreSQL.
0

Using the declarative approach:

from sqlalchemy import String
from sqlalchemy.orm import DeclarativeBase, Mapped, MappedAsDataclass, mapped_column

class Edge(MappedAsDataclass, DeclarativeBase):
    sources: Mapped[list] = mapped_column(ARRAY(String), default_factory=list)

3 Comments

dn why, but images: Mapped[list] = mapped_column(ARRAY(String), default_factory=list) gives me error: Attribute 'images' ... includes dataclasses argument(s): 'default_factory' but class does not specify SQLAlchemy native dataclass configuration
@DamirNafikov, I have updated the answer with proper class definition that should fix the error you got.
got it) i just set server_default="{}"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.