On Wed, Feb 27, 2019 at 11:38 PM Pavel Pristupa <[email protected]> wrote:
>
> Yes, just a typo.
> The actual problem is the following:
>
> When I try to add back_populates('user') to User.billing_addresses and
> User.shipping_addresses relationships, I get the error:
> User.billing_addresses and back-reference Address.user are both of the same
> direction <symbol 'ONETOMANY>. Did you mean to set remote_side on the
> many-to-one side?
once I correct for the syntactical issues I can't reproduce this
error. Please provide a proper MCVE, thanks! see below
import sqlalchemy as sa
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, configure_mappers, Session
Base = declarative_base()
class User(Base):
__tablename__ = 'user'
id = sa.Column(sa.Integer, primary_key=True)
billing_addresses = relationship(
"Address",
primaryjoin="and_(User.id==Address.user_id,
Address.is_billing.is_(True))",
back_populates="user",
uselist=True,
)
shipping_addresses = relationship(
"Address",
primaryjoin="and_(User.id==Address.user_id,
Address.is_billing.is_(False))",
back_populates="user",
uselist=True,
)
class Address(Base):
__tablename__ = 'address'
id = sa.Column(sa.Integer, primary_key=True)
is_billing = sa.Column(
sa.Boolean
) # Let it be a discriminator for whether it's a billing or shipping
user_id = sa.Column(sa.Integer, sa.ForeignKey("user.id"), nullable=False)
user = relationship(User)
configure_mappers()
e = sa.create_engine("sqlite://", echo=True)
Base.metadata.create_all(e)
s = Session(e)
a1, a2 = Address(), Address()
u1 = User(billing_addresses=[a1], shipping_addresses=[a2])
assert a1.user is u1
assert a2.user is u1
s.add(u1)
s.commit()
output
$ python test.py
2019-02-28 08:19:19,174 INFO sqlalchemy.engine.base.Engine SELECT
CAST('test plain returns' AS VARCHAR(60)) AS anon_1
2019-02-28 08:19:19,174 INFO sqlalchemy.engine.base.Engine ()
2019-02-28 08:19:19,175 INFO sqlalchemy.engine.base.Engine SELECT
CAST('test unicode returns' AS VARCHAR(60)) AS anon_1
2019-02-28 08:19:19,175 INFO sqlalchemy.engine.base.Engine ()
2019-02-28 08:19:19,176 INFO sqlalchemy.engine.base.Engine PRAGMA
table_info("user")
2019-02-28 08:19:19,176 INFO sqlalchemy.engine.base.Engine ()
2019-02-28 08:19:19,176 INFO sqlalchemy.engine.base.Engine PRAGMA
table_info("address")
2019-02-28 08:19:19,177 INFO sqlalchemy.engine.base.Engine ()
2019-02-28 08:19:19,177 INFO sqlalchemy.engine.base.Engine
CREATE TABLE user (
id INTEGER NOT NULL,
PRIMARY KEY (id)
)
2019-02-28 08:19:19,177 INFO sqlalchemy.engine.base.Engine ()
2019-02-28 08:19:19,178 INFO sqlalchemy.engine.base.Engine COMMIT
2019-02-28 08:19:19,178 INFO sqlalchemy.engine.base.Engine
CREATE TABLE address (
id INTEGER NOT NULL,
is_billing BOOLEAN,
user_id INTEGER NOT NULL,
PRIMARY KEY (id),
CHECK (is_billing IN (0, 1)),
FOREIGN KEY(user_id) REFERENCES user (id)
)
2019-02-28 08:19:19,179 INFO sqlalchemy.engine.base.Engine ()
2019-02-28 08:19:19,179 INFO sqlalchemy.engine.base.Engine COMMIT
2019-02-28 08:19:19,180 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2019-02-28 08:19:19,181 INFO sqlalchemy.engine.base.Engine INSERT INTO
user DEFAULT VALUES
2019-02-28 08:19:19,181 INFO sqlalchemy.engine.base.Engine ()
2019-02-28 08:19:19,182 INFO sqlalchemy.engine.base.Engine INSERT INTO
address (is_billing, user_id) VALUES (?, ?)
2019-02-28 08:19:19,182 INFO sqlalchemy.engine.base.Engine (None, 1)
2019-02-28 08:19:19,182 INFO sqlalchemy.engine.base.Engine INSERT INTO
address (is_billing, user_id) VALUES (?, ?)
2019-02-28 08:19:19,183 INFO sqlalchemy.engine.base.Engine (None, 1)
2019-02-28 08:19:19,183 INFO sqlalchemy.engine.base.Engine COMMIT
>
> среда, 27 февраля 2019 г., 1:03:40 UTC+7 пользователь Mike Bayer написал:
>>
>> you are missing and_():
>>
>> billing_addresses = relationship('Address',
>> primary_join='and_(User.id==Address.id,
>> Address.is_billing.is_(True))', uselist=True)
>>
>>
>> On Tue, Feb 26, 2019 at 5:44 AM Pavel Pristupa <[email protected]> wrote:
>> >
>> > Hi everybody!
>> >
>> > Is there a way to use primary_join with back_populates in the following
>> > case?
>> >
>> > I have two entities (sorry, I may be wrong with the exact syntax):
>> >
>> >
>> > class User(Base):
>> > id = sa.Column(sa.Integer, primary_key=True)
>> > billing_addresses = relationship('Address',
>> > primary_join='User.id==Address.id, Address.is_billing.is_(True)',
>> > uselist=True)
>> > shipping_addresses = relationship('Address',
>> > primary_join='User.id==Address.id, Address.is_billing.is_(False)',
>> > uselist=True)
>> >
>> >
>> > class Address(Base):
>> > id = sa.Column(sa.Integer, primary_key=True)
>> > is_billing = sa.Column(sa.Boolean) # Let it be a discriminator for
>> > whether it's a billing or shipping
>> > user_id = sa.Column(sa.Integer, sa.ForeignKey('User.id'), nullable=False)
>> > user = relationship(User)
>> >
>> >
>> > I had to add uselist=True explicitly, but that's not a problem.
>> > When I try to add back_populates('user') to User.billing_addresses and
>> > User.shipping_addresses relationships, I get the error:
>> > User.billing_addresses and back-reference Address.user are both of the
>> > same direction <symbol 'ONETOMANY>. Did you mean to set remote_side on
>> > the many-to-one side?
>> >
>> > Could you help me what and where I should fix?
>> >
>> > --
>> > SQLAlchemy -
>> > The Python SQL Toolkit and Object Relational Mapper
>> >
>> > http://www.sqlalchemy.org/
>> >
>> > To post example code, please provide an MCVE: Minimal, Complete, and
>> > Verifiable Example. See http://stackoverflow.com/help/mcve for a full
>> > description.
>> > ---
>> > You received this message because you are subscribed to the Google Groups
>> > "sqlalchemy" group.
>> > To unsubscribe from this group and stop receiving emails from it, send an
>> > email to [email protected].
>> > To post to this group, send email to [email protected].
>> > Visit this group at https://groups.google.com/group/sqlalchemy.
>> > For more options, visit https://groups.google.com/d/optout.
>
> --
> SQLAlchemy -
> The Python SQL Toolkit and Object Relational Mapper
>
> http://www.sqlalchemy.org/
>
> To post example code, please provide an MCVE: Minimal, Complete, and
> Verifiable Example. See http://stackoverflow.com/help/mcve for a full
> description.
> ---
> You received this message because you are subscribed to the Google Groups
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at https://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/d/optout.
--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper
http://www.sqlalchemy.org/
To post example code, please provide an MCVE: Minimal, Complete, and Verifiable
Example. See http://stackoverflow.com/help/mcve for a full description.
---
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.